#pragma once
/*
 *  FakeIt - A Simplified C++ Mocking Framework
 *  Copyright (c) Eran Pe'er 2013
 *  Generated: 2019-06-01 12:15:07.986646
 *  Distributed under the MIT License. Please refer to the LICENSE file at:
 *  https://github.com/eranpeer/FakeIt
 */





#include <functional>
#include <memory>
#include <set>
#include <vector>
#include <stdexcept>

#if defined (__GNUG__) || _MSC_VER >= 1900
#define THROWS noexcept(false)
#define NO_THROWS noexcept(true)
#elif defined (_MSC_VER)
																														#define THROWS throw(...)
#define NO_THROWS
#endif

#include <typeinfo>
#include <unordered_set>
#include <tuple>
#include <string>
#include <iosfwd>
#include <atomic>
#include <tuple>


namespace fakeit
{

	template<class C>
	struct naked_type
	{
		typedef typename std::remove_cv<typename std::remove_reference<C>::type>::type type;
	};

	template<class T>
	struct tuple_arg
	{
		typedef T type;
	};
	template<class T>
	struct tuple_arg<T&>
	{
		typedef T& type;
	};
	template<class T>
	struct tuple_arg<T&&>
	{
		typedef T&& type;
	};




	template<typename... arglist>
	using ArgumentsTuple = std::tuple<arglist...>;

	template<class T>
	struct test_arg
	{
		typedef T& type;
	};
	template<class T>
	struct test_arg<T&>
	{
		typedef T& type;
	};
	template<class T>
	struct test_arg<T&&>
	{
		typedef T& type;
	};

	template<class T>
	struct production_arg
	{
		typedef T& type;
	};
	template<class T>
	struct production_arg<T&>
	{
		typedef T& type;
	};
	template<class T>
	struct production_arg<T&&>
	{
		typedef T&& type;
	};

	template<typename T>
	class is_ostreamable
	{
		struct no
		{
		};
#if defined(_MSC_VER) && _MSC_VER < 1900
																																template <typename T1>
        static decltype(operator<<(std::declval<std::ostream&>(), std::declval<const T1>())) test(std::ostream &s, const T1 &t);
#else

		template<typename T1>
		static auto test(std::ostream& s, const T1& t) -> decltype(s << t);

#endif

		static no test(...);

	public:

		static const bool value =
				std::is_arithmetic<T>::value ||
				std::is_pointer<T>::value ||
				std::is_same<decltype(test(*(std::ostream*)nullptr,
						std::declval<T>())), std::ostream&>::value;
	};


	template<>
	class is_ostreamable<std::ios_base& (*)(std::ios_base&)>
	{
	public:
		static const bool value = true;
	};

	template<typename CharT, typename Traits>
	class is_ostreamable<std::basic_ios<CharT, Traits>& (*)(std::basic_ios<CharT, Traits>&)>
	{
	public:
		static const bool value = true;
	};

	template<typename CharT, typename Traits>
	class is_ostreamable<std::basic_ostream<CharT, Traits>& (*)(std::basic_ostream<CharT, Traits>&)>
	{
	public:
		static const bool value = true;
	};

	template<typename R, typename... arglist>
	struct VTableMethodType
	{
#if defined (__GNUG__)

		typedef R(* type)(void*, arglist...);

#elif defined (_MSC_VER)
		typedef R(__thiscall *type)(void *, arglist...);
#endif
	};
}

#include <typeinfo>
#include <tuple>
#include <string>
#include <iosfwd>
#include <sstream>
#include <string>

namespace fakeit
{

	struct FakeitContext;

	template<typename C>
	struct MockObject
	{
		virtual ~MockObject() THROWS
		{
		};

		virtual C& get() = 0;

		virtual FakeitContext& getFakeIt() = 0;
	};

	struct MethodInfo
	{

		static unsigned int nextMethodOrdinal()
		{
			static std::atomic_uint ordinal{ 0 };
			return ++ordinal;
		}

		MethodInfo(unsigned int anId, std::string aName) :
				_id(anId), _name(aName)
		{
		}

		unsigned int id() const
		{
			return _id;
		}

		std::string name() const
		{
			return _name;
		}

		void setName(const std::string& value)
		{
			_name = value;
		}

	private:
		unsigned int _id;
		std::string _name;
	};

	struct UnknownMethod
	{

		static MethodInfo& instance()
		{
			static MethodInfo instance(MethodInfo::nextMethodOrdinal(), "unknown");
			return instance;
		}

	};

}
namespace fakeit
{
	class Destructible
	{
	public:
		virtual ~Destructible()
		{
		}
	};
}

namespace fakeit
{

	struct Invocation : Destructible
	{

		static unsigned int nextInvocationOrdinal()
		{
			static std::atomic_uint invocationOrdinal{ 0 };
			return ++invocationOrdinal;
		}

		struct Matcher
		{

			virtual ~Matcher() THROWS
			{
			}

			virtual bool matches(Invocation& invocation) = 0;

			virtual std::string format() const = 0;
		};

		Invocation(unsigned int ordinal, MethodInfo& method) :
				_ordinal(ordinal), _method(method), _isVerified(false)
		{
		}

		virtual ~Invocation() override = default;

		unsigned int getOrdinal() const
		{
			return _ordinal;
		}

		MethodInfo& getMethod() const
		{
			return _method;
		}

		void markAsVerified()
		{
			_isVerified = true;
		}

		bool isVerified() const
		{
			return _isVerified;
		}

		virtual std::string format() const = 0;

	private:
		const unsigned int _ordinal;
		MethodInfo& _method;
		bool _isVerified;
	};

}

#include <iosfwd>
#include <tuple>
#include <string>
#include <sstream>
#include <ostream>

namespace fakeit
{

	template<typename T, class Enable = void>
	struct Formatter;

	template<>
	struct Formatter<bool>
	{
		static std::string format(bool const& val)
		{
			return val ? "true" : "false";
		}
	};

	template<>
	struct Formatter<char>
	{
		static std::string format(char const& val)
		{
			std::string s;
			s += "'";
			s += val;
			s += "'";
			return s;
		}
	};

	template<>
	struct Formatter<char const*>
	{
		static std::string format(char const* const& val)
		{
			std::string s;
			if (val != nullptr)
			{
				s += '"';
				s += val;
				s += '"';
			}
			else
			{
				s = "[nullptr]";
			}
			return s;
		}
	};

	template<>
	struct Formatter<char*>
	{
		static std::string format(char* const& val)
		{
			return Formatter<char const*>::format(val);
		}
	};

	template<class C>
	struct Formatter<C, typename std::enable_if<!is_ostreamable<C>::value>::type>
	{
		static std::string format(C const&)
		{
			return "?";
		}
	};

	template<class C>
	struct Formatter<C, typename std::enable_if<is_ostreamable<C>::value>::type>
	{
		static std::string format(C const& val)
		{
			std::ostringstream os;
			os << val;
			return os.str();
		}
	};


	template<typename T>
	using TypeFormatter = Formatter<typename fakeit::naked_type<T>::type>;
}

namespace fakeit
{


	template<class Tuple, std::size_t N>
	struct TuplePrinter
	{
		static void print(std::ostream& strm, const Tuple& t)
		{
			TuplePrinter<Tuple, N - 1>::print(strm, t);
			strm << ", " << fakeit::TypeFormatter<decltype(std::get<N - 1>(t))>::format(std::get<N - 1>(t));
		}
	};

	template<class Tuple>
	struct TuplePrinter<Tuple, 1>
	{
		static void print(std::ostream& strm, const Tuple& t)
		{
			strm << fakeit::TypeFormatter<decltype(std::get<0>(t))>::format(std::get<0>(t));
		}
	};

	template<class Tuple>
	struct TuplePrinter<Tuple, 0>
	{
		static void print(std::ostream&, const Tuple&)
		{
		}
	};

	template<class ... Args>
	void print(std::ostream& strm, const std::tuple<Args...>& t)
	{
		strm << "(";
		TuplePrinter<decltype(t), sizeof...(Args)>::print(strm, t);
		strm << ")";
	}

	template<class ... Args>
	std::ostream& operator<<(std::ostream& strm, const std::tuple<Args...>& t)
	{
		print(strm, t);
		return strm;
	}

}


namespace fakeit
{

	template<typename ... arglist>
	struct ActualInvocation : public Invocation
	{

		struct Matcher : public virtual Destructible
		{
			virtual bool matches(ActualInvocation<arglist...>& actualInvocation) = 0;

			virtual std::string format() const = 0;
		};

		ActualInvocation(unsigned int ordinal, MethodInfo& method,
				const typename fakeit::production_arg<arglist>::type... args) :
				Invocation(ordinal, method), _matcher{ nullptr }, actualArguments{ std::forward<arglist>(args)... }
		{
		}

		ArgumentsTuple<arglist...>& getActualArguments()
		{
			return actualArguments;
		}


		void setActualMatcher(Matcher* matcher)
		{
			this->_matcher = matcher;
		}

		Matcher* getActualMatcher()
		{
			return _matcher;
		}

		virtual std::string format() const override
		{
			std::ostringstream out;
			out << getMethod().name();
			print(out, actualArguments);
			return out.str();
		}

	private:

		Matcher* _matcher;
		ArgumentsTuple<arglist...> actualArguments;
	};

	template<typename ... arglist>
	std::ostream& operator<<(std::ostream& strm, const ActualInvocation<arglist...>& ai)
	{
		strm << ai.format();
		return strm;
	}

}


#include <unordered_set>

namespace fakeit
{

	struct ActualInvocationsContainer
	{
		virtual void clear() = 0;

		virtual ~ActualInvocationsContainer() NO_THROWS
		{
		}
	};

	struct ActualInvocationsSource
	{
		virtual void getActualInvocations(std::unordered_set<fakeit::Invocation*>& into) const = 0;

		virtual ~ActualInvocationsSource() NO_THROWS
		{
		}
	};

	struct InvocationsSourceProxy : public ActualInvocationsSource
	{

		InvocationsSourceProxy(ActualInvocationsSource* inner) :
				_inner(inner)
		{
		}

		void getActualInvocations(std::unordered_set<fakeit::Invocation*>& into) const override
		{
			_inner->getActualInvocations(into);
		}

	private:
		std::shared_ptr<ActualInvocationsSource> _inner;
	};

	struct UnverifiedInvocationsSource : public ActualInvocationsSource
	{

		UnverifiedInvocationsSource(InvocationsSourceProxy decorated) : _decorated(decorated)
		{
		}

		void getActualInvocations(std::unordered_set<fakeit::Invocation*>& into) const override
		{
			std::unordered_set<fakeit::Invocation*> all;
			_decorated.getActualInvocations(all);
			for (fakeit::Invocation* i : all)
			{
				if (!i->isVerified())
				{
					into.insert(i);
				}
			}
		}

	private:
		InvocationsSourceProxy _decorated;
	};

	struct AggregateInvocationsSource : public ActualInvocationsSource
	{

		AggregateInvocationsSource(std::vector<ActualInvocationsSource*>& sources) : _sources(sources)
		{
		}

		void getActualInvocations(std::unordered_set<fakeit::Invocation*>& into) const override
		{
			std::unordered_set<fakeit::Invocation*> tmp;
			for (ActualInvocationsSource* source : _sources)
			{
				source->getActualInvocations(tmp);
			}
			filter(tmp, into);
		}

	protected:
		bool shouldInclude(fakeit::Invocation*) const
		{
			return true;
		}

	private:
		std::vector<ActualInvocationsSource*> _sources;

		void filter(std::unordered_set<Invocation*>& source, std::unordered_set<Invocation*>& target) const
		{
			for (Invocation* i:source)
			{
				if (shouldInclude(i))
				{
					target.insert(i);
				}
			}
		}
	};
}

namespace fakeit
{

	class Sequence
	{
	private:

	protected:

		Sequence()
		{
		}

		virtual ~Sequence() THROWS
		{
		}

	public:


		virtual void getExpectedSequence(std::vector<Invocation::Matcher*>& into) const = 0;


		virtual void getInvolvedMocks(std::vector<ActualInvocationsSource*>& into) const = 0;

		virtual unsigned int size() const = 0;

		friend class VerifyFunctor;
	};

	class ConcatenatedSequence : public virtual Sequence
	{
	private:
		const Sequence& s1;
		const Sequence& s2;

	protected:
		ConcatenatedSequence(const Sequence& seq1, const Sequence& seq2) :
				s1(seq1), s2(seq2)
		{
		}

	public:

		virtual ~ConcatenatedSequence()
		{
		}

		unsigned int size() const override
		{
			return s1.size() + s2.size();
		}

		const Sequence& getLeft() const
		{
			return s1;
		}

		const Sequence& getRight() const
		{
			return s2;
		}

		void getExpectedSequence(std::vector<Invocation::Matcher*>& into) const override
		{
			s1.getExpectedSequence(into);
			s2.getExpectedSequence(into);
		}

		virtual void getInvolvedMocks(std::vector<ActualInvocationsSource*>& into) const override
		{
			s1.getInvolvedMocks(into);
			s2.getInvolvedMocks(into);
		}

		friend inline ConcatenatedSequence operator+(const Sequence& s1, const Sequence& s2);
	};

	class RepeatedSequence : public virtual Sequence
	{
	private:
		const Sequence& _s;
		const int times;

	protected:
		RepeatedSequence(const Sequence& s, const int t) :
				_s(s), times(t)
		{
		}

	public:

		~RepeatedSequence()
		{
		}

		unsigned int size() const override
		{
			return _s.size() * times;
		}

		friend inline RepeatedSequence operator*(const Sequence& s, int times);

		friend inline RepeatedSequence operator*(int times, const Sequence& s);

		void getInvolvedMocks(std::vector<ActualInvocationsSource*>& into) const override
		{
			_s.getInvolvedMocks(into);
		}

		void getExpectedSequence(std::vector<Invocation::Matcher*>& into) const override
		{
			for (int i = 0; i < times; i++)
				_s.getExpectedSequence(into);
		}

		int getTimes() const
		{
			return times;
		}

		const Sequence& getSequence() const
		{
			return _s;
		}
	};

	inline ConcatenatedSequence operator+(const Sequence& s1, const Sequence& s2)
	{
		return ConcatenatedSequence(s1, s2);
	}

	inline RepeatedSequence operator*(const Sequence& s, int times)
	{
		if (times <= 0)
			throw std::invalid_argument("times");
		return RepeatedSequence(s, times);
	}

	inline RepeatedSequence operator*(int times, const Sequence& s)
	{
		if (times <= 0)
			throw std::invalid_argument("times");
		return RepeatedSequence(s, times);
	}

}

namespace fakeit
{

	enum class VerificationType
	{
		Exact, AtLeast, NoMoreInvocations
	};

	enum class UnexpectedType
	{
		Unmocked, Unmatched
	};

	struct VerificationEvent
	{

		VerificationEvent(VerificationType aVerificationType) :
				_verificationType(aVerificationType), _line(0)
		{
		}

		virtual ~VerificationEvent() = default;

		VerificationType verificationType() const
		{
			return _verificationType;
		}

		void setFileInfo(const char* aFile, int aLine, const char* aCallingMethod)
		{
			_file = aFile;
			_callingMethod = aCallingMethod;
			_line = aLine;
		}

		const char* file() const
		{
			return _file;
		}

		int line() const
		{
			return _line;
		}

		const char* callingMethod() const
		{
			return _callingMethod;
		}

	private:
		VerificationType _verificationType;
		const char* _file;
		int _line;
		const char* _callingMethod;
	};

	struct NoMoreInvocationsVerificationEvent : public VerificationEvent
	{

		~NoMoreInvocationsVerificationEvent() = default;

		NoMoreInvocationsVerificationEvent(
				std::vector<Invocation*>& allTheIvocations,
				std::vector<Invocation*>& anUnverifedIvocations) :
				VerificationEvent(VerificationType::NoMoreInvocations),
				_allIvocations(allTheIvocations),
				_unverifedIvocations(anUnverifedIvocations)
		{
		}

		const std::vector<Invocation*>& allIvocations() const
		{
			return _allIvocations;
		}

		const std::vector<Invocation*>& unverifedIvocations() const
		{
			return _unverifedIvocations;
		}

	private:
		const std::vector<Invocation*> _allIvocations;
		const std::vector<Invocation*> _unverifedIvocations;
	};

	struct SequenceVerificationEvent : public VerificationEvent
	{

		~SequenceVerificationEvent() = default;

		SequenceVerificationEvent(VerificationType aVerificationType,
				std::vector<Sequence*>& anExpectedPattern,
				std::vector<Invocation*>& anActualSequence,
				int anExpectedCount,
				int anActualCount) :
				VerificationEvent(aVerificationType),
				_expectedPattern(anExpectedPattern),
				_actualSequence(anActualSequence),
				_expectedCount(anExpectedCount),
				_actualCount(anActualCount)
		{
		}

		const std::vector<Sequence*>& expectedPattern() const
		{
			return _expectedPattern;
		}

		const std::vector<Invocation*>& actualSequence() const
		{
			return _actualSequence;
		}

		int expectedCount() const
		{
			return _expectedCount;
		}

		int actualCount() const
		{
			return _actualCount;
		}

	private:
		const std::vector<Sequence*> _expectedPattern;
		const std::vector<Invocation*> _actualSequence;
		const int _expectedCount;
		const int _actualCount;
	};

	struct UnexpectedMethodCallEvent
	{
		UnexpectedMethodCallEvent(UnexpectedType unexpectedType, const Invocation& invocation) :
				_unexpectedType(unexpectedType), _invocation(invocation)
		{
		}

		const Invocation& getInvocation() const
		{
			return _invocation;
		}

		UnexpectedType getUnexpectedType() const
		{
			return _unexpectedType;
		}

		const UnexpectedType _unexpectedType;
		const Invocation& _invocation;
	};

}

namespace fakeit
{

	struct VerificationEventHandler
	{
		virtual void handle(const SequenceVerificationEvent& e) = 0;

		virtual void handle(const NoMoreInvocationsVerificationEvent& e) = 0;
	};

	struct EventHandler : public VerificationEventHandler
	{
		using VerificationEventHandler::handle;

		virtual void handle(const UnexpectedMethodCallEvent& e) = 0;
	};

}

#include <vector>
#include <string>

namespace fakeit
{

	struct UnexpectedMethodCallEvent;
	struct SequenceVerificationEvent;
	struct NoMoreInvocationsVerificationEvent;

	struct EventFormatter
	{

		virtual std::string format(const fakeit::UnexpectedMethodCallEvent& e) = 0;

		virtual std::string format(const fakeit::SequenceVerificationEvent& e) = 0;

		virtual std::string format(const fakeit::NoMoreInvocationsVerificationEvent& e) = 0;

	};

}
#ifdef FAKEIT_ASSERT_ON_UNEXPECTED_METHOD_INVOCATION
#include <cassert>
#endif

namespace fakeit
{

	struct FakeitContext : public EventHandler, protected EventFormatter
	{

		virtual ~FakeitContext() = default;

		void handle(const UnexpectedMethodCallEvent& e) override
		{
			fireEvent(e);
			auto& eh = getTestingFrameworkAdapter();
#ifdef FAKEIT_ASSERT_ON_UNEXPECTED_METHOD_INVOCATION
			assert(!"Unexpected method invocation");
#endif
			eh.handle(e);
		}

		void handle(const SequenceVerificationEvent& e) override
		{
			fireEvent(e);
			auto& eh = getTestingFrameworkAdapter();
			return eh.handle(e);
		}

		void handle(const NoMoreInvocationsVerificationEvent& e) override
		{
			fireEvent(e);
			auto& eh = getTestingFrameworkAdapter();
			return eh.handle(e);
		}

		std::string format(const UnexpectedMethodCallEvent& e) override
		{
			auto& eventFormatter = getEventFormatter();
			return eventFormatter.format(e);
		}

		std::string format(const SequenceVerificationEvent& e) override
		{
			auto& eventFormatter = getEventFormatter();
			return eventFormatter.format(e);
		}

		std::string format(const NoMoreInvocationsVerificationEvent& e) override
		{
			auto& eventFormatter = getEventFormatter();
			return eventFormatter.format(e);
		}

		void addEventHandler(EventHandler& eventListener)
		{
			_eventListeners.push_back(&eventListener);
		}

		void clearEventHandlers()
		{
			_eventListeners.clear();
		}

	protected:
		virtual EventHandler& getTestingFrameworkAdapter() = 0;

		virtual EventFormatter& getEventFormatter() = 0;

	private:
		std::vector<EventHandler*> _eventListeners;

		void fireEvent(const NoMoreInvocationsVerificationEvent& evt)
		{
			for (auto listener : _eventListeners)
				listener->handle(evt);
		}

		void fireEvent(const UnexpectedMethodCallEvent& evt)
		{
			for (auto listener : _eventListeners)
				listener->handle(evt);
		}

		void fireEvent(const SequenceVerificationEvent& evt)
		{
			for (auto listener : _eventListeners)
				listener->handle(evt);
		}

	};

}

#include <iostream>
#include <iosfwd>

namespace fakeit
{

	struct DefaultEventFormatter : public EventFormatter
	{

		virtual std::string format(const UnexpectedMethodCallEvent& e) override
		{
			std::ostringstream out;
			out << "Unexpected method invocation: ";
			out << e.getInvocation().format() << std::endl;
			if (UnexpectedType::Unmatched == e.getUnexpectedType())
			{
				out << "  Could not find any recorded behavior to support this method call.";
			}
			else
			{
				out << "  An unmocked method was invoked. All used virtual methods must be stubbed!";
			}
			return out.str();
		}


		virtual std::string format(const SequenceVerificationEvent& e) override
		{
			std::ostringstream out;
			out << "Verification error" << std::endl;

			out << "Expected pattern: ";
			const std::vector<fakeit::Sequence*> expectedPattern = e.expectedPattern();
			out << formatExpectedPattern(expectedPattern) << std::endl;

			out << "Expected matches: ";
			formatExpectedCount(out, e.verificationType(), e.expectedCount());
			out << std::endl;

			out << "Actual matches  : " << e.actualCount() << std::endl;

			auto actualSequence = e.actualSequence();
			out << "Actual sequence : total of " << actualSequence.size() << " actual invocations";
			if (actualSequence.size() == 0)
			{
				out << ".";
			}
			else
			{
				out << ":" << std::endl;
			}
			formatInvocationList(out, actualSequence);

			return out.str();
		}

		virtual std::string format(const NoMoreInvocationsVerificationEvent& e) override
		{
			std::ostringstream out;
			out << "Verification error" << std::endl;
			out << "Expected no more invocations!! but the following unverified invocations were found:" << std::endl;
			formatInvocationList(out, e.unverifedIvocations());
			return out.str();
		}

		static std::string formatExpectedPattern(const std::vector<fakeit::Sequence*>& expectedPattern)
		{
			std::string expectedPatternStr;
			for (unsigned int i = 0; i < expectedPattern.size(); i++)
			{
				Sequence* s = expectedPattern[i];
				expectedPatternStr += formatSequence(*s);
				if (i < expectedPattern.size() - 1)
					expectedPatternStr += " ... ";
			}
			return expectedPatternStr;
		}

	private:

		static std::string formatSequence(const Sequence& val)
		{
			const ConcatenatedSequence* cs = dynamic_cast<const ConcatenatedSequence*>(&val);
			if (cs)
			{
				return format(*cs);
			}
			const RepeatedSequence* rs = dynamic_cast<const RepeatedSequence*>(&val);
			if (rs)
			{
				return format(*rs);
			}


			std::vector<Invocation::Matcher*> vec;
			val.getExpectedSequence(vec);
			return vec[0]->format();
		}

		static void formatExpectedCount(std::ostream& out, fakeit::VerificationType verificationType,
				int expectedCount)
		{
			if (verificationType == fakeit::VerificationType::Exact)
				out << "exactly ";

			if (verificationType == fakeit::VerificationType::AtLeast)
				out << "at least ";

			out << expectedCount;
		}

		static void formatInvocationList(std::ostream& out, const std::vector<fakeit::Invocation*>& actualSequence)
		{
			size_t max_size = actualSequence.size();
			if (max_size > 50)
				max_size = 50;

			for (unsigned int i = 0; i < max_size; i++)
			{
				out << "  ";
				auto invocation = actualSequence[i];
				out << invocation->format();
				if (i < max_size - 1)
					out << std::endl;
			}

			if (actualSequence.size() > max_size)
				out << std::endl << "  ...";
		}

		static std::string format(const ConcatenatedSequence& val)
		{
			std::ostringstream out;
			out << formatSequence(val.getLeft()) << " + " << formatSequence(val.getRight());
			return out.str();
		}

		static std::string format(const RepeatedSequence& val)
		{
			std::ostringstream out;
			const ConcatenatedSequence* cs = dynamic_cast<const ConcatenatedSequence*>(&val.getSequence());
			const RepeatedSequence* rs = dynamic_cast<const RepeatedSequence*>(&val.getSequence());
			if (rs || cs)
				out << '(';
			out << formatSequence(val.getSequence());
			if (rs || cs)
				out << ')';

			out << " * " << val.getTimes();
			return out.str();
		}
	};
}

#include <exception>


namespace fakeit
{
#if __cplusplus >= 201703L

	inline bool UncaughtException()
	{
		return std::uncaught_exceptions() >= 1;
	}

#else
																															inline bool UncaughtException () {
      return std::uncaught_exception();
    }
#endif

	struct FakeitException
	{
		std::exception err;

		virtual ~FakeitException() = default;

		virtual std::string what() const = 0;

		friend std::ostream& operator<<(std::ostream& os, const FakeitException& val)
		{
			os << val.what();
			return os;
		}
	};


	struct UnexpectedMethodCallException : public FakeitException
	{

		UnexpectedMethodCallException(std::string format) :
				_format(format)
		{
		}

		virtual std::string what() const override
		{
			return _format;
		}

	private:
		std::string _format;
	};

}

namespace fakeit
{

	struct DefaultEventLogger : public fakeit::EventHandler
	{

		DefaultEventLogger(EventFormatter& formatter) : _formatter(formatter), _out(std::cout)
		{
		}

		virtual void handle(const UnexpectedMethodCallEvent& e) override
		{
			_out << _formatter.format(e) << std::endl;
		}

		virtual void handle(const SequenceVerificationEvent& e) override
		{
			_out << _formatter.format(e) << std::endl;
		}

		virtual void handle(const NoMoreInvocationsVerificationEvent& e) override
		{
			_out << _formatter.format(e) << std::endl;
		}

	private:
		EventFormatter& _formatter;
		std::ostream& _out;
	};

}

namespace fakeit
{

	class AbstractFakeit : public FakeitContext
	{
	public:
		virtual ~AbstractFakeit() = default;

	protected:

		virtual fakeit::EventHandler& accessTestingFrameworkAdapter() = 0;

		virtual EventFormatter& accessEventFormatter() = 0;
	};

	class DefaultFakeit : public AbstractFakeit
	{
		DefaultEventFormatter _formatter;
		fakeit::EventFormatter* _customFormatter;
		fakeit::EventHandler* _testingFrameworkAdapter;

	public:

		DefaultFakeit() : _formatter(),
						  _customFormatter(nullptr),
						  _testingFrameworkAdapter(nullptr)
		{
		}

		virtual ~DefaultFakeit() = default;

		void setCustomEventFormatter(fakeit::EventFormatter& customEventFormatter)
		{
			_customFormatter = &customEventFormatter;
		}

		void resetCustomEventFormatter()
		{
			_customFormatter = nullptr;
		}

		void setTestingFrameworkAdapter(fakeit::EventHandler& testingFrameforkAdapter)
		{
			_testingFrameworkAdapter = &testingFrameforkAdapter;
		}

		void resetTestingFrameworkAdapter()
		{
			_testingFrameworkAdapter = nullptr;
		}

	protected:

		fakeit::EventHandler& getTestingFrameworkAdapter() override
		{
			if (_testingFrameworkAdapter)
				return *_testingFrameworkAdapter;
			return accessTestingFrameworkAdapter();
		}

		EventFormatter& getEventFormatter() override
		{
			if (_customFormatter)
				return *_customFormatter;
			return accessEventFormatter();
		}

		EventFormatter& accessEventFormatter() override
		{
			return _formatter;
		}

	};
}

#include <string>
#include <sstream>
#include <iomanip>

namespace fakeit
{

	template<typename T>
	static std::string to_string(const T& n)
	{
		std::ostringstream stm;
		stm << n;
		return stm.str();
	}

}

namespace fakeit
{

	struct VerificationException : public std::exception
	{
		virtual ~VerificationException() NO_THROWS
		{
		};

		VerificationException(std::string format) :
				_format(format)
		{
		}

		friend std::ostream& operator<<(std::ostream& os, const VerificationException& val)
		{
			os << val.what();
			return os;
		}

		void setFileInfo(std::string aFile, int aLine, std::string aCallingMethod)
		{
			_file = aFile;
			_callingMethod = aCallingMethod;
			_line = aLine;
		}

		const std::string& file() const
		{
			return _file;
		}

		int line() const
		{
			return _line;
		}

		const std::string& callingMethod() const
		{
			return _callingMethod;
		}

		const char* what() const NO_THROWS override
		{
			return _format.c_str();
		}

	private:
		std::string _file;
		int _line;
		std::string _callingMethod;
		std::string _format;
	};

	struct NoMoreInvocationsVerificationException : public VerificationException
	{
		NoMoreInvocationsVerificationException(std::string format) :
				VerificationException(format)
		{
		}
	};

	struct SequenceVerificationException : public VerificationException
	{
		SequenceVerificationException(std::string format) :
				VerificationException(format)
		{
		}
	};

	struct StandaloneAdapter : public EventHandler
	{

		std::string formatLineNumner(std::string file, int num)
		{
#ifndef __GNUG__
			return file + std::string("(") + fakeit::to_string(num) + std::string(")");
#else
			return file + std::string(":") + fakeit::to_string(num);
#endif
		}

		virtual ~StandaloneAdapter() = default;

		StandaloneAdapter(EventFormatter& formatter)
				: _formatter(formatter)
		{
		}

		virtual void handle(const UnexpectedMethodCallEvent& evt) override
		{
			std::string format = _formatter.format(evt);
			UnexpectedMethodCallException ex(format);
			throw ex;
		}

		virtual void handle(const SequenceVerificationEvent& evt) override
		{
			std::string format(formatLineNumner(evt.file(), evt.line()) + ": " + _formatter.format(evt));
			SequenceVerificationException e(format);
			e.setFileInfo(evt.file(), evt.line(), evt.callingMethod());
			throw e;
		}

		virtual void handle(const NoMoreInvocationsVerificationEvent& evt) override
		{
			std::string format(formatLineNumner(evt.file(), evt.line()) + ": " + _formatter.format(evt));
			NoMoreInvocationsVerificationException e(format);
			e.setFileInfo(evt.file(), evt.line(), evt.callingMethod());
			throw e;
		}

	private:
		EventFormatter& _formatter;
	};

	class StandaloneFakeit : public DefaultFakeit
	{

	public:
		virtual ~StandaloneFakeit() = default;

		StandaloneFakeit() : _standaloneAdapter(*this)
		{
		}

		static StandaloneFakeit& getInstance()
		{
			static StandaloneFakeit instance;
			return instance;
		}

	protected:

		fakeit::EventHandler& accessTestingFrameworkAdapter() override
		{
			return _standaloneAdapter;
		}

	private:

		StandaloneAdapter _standaloneAdapter;
	};
}

static fakeit::DefaultFakeit& Fakeit = fakeit::StandaloneFakeit::getInstance();


#include <type_traits>
#include <unordered_set>

#include <memory>

#undef max

#include <functional>
#include <type_traits>
#include <vector>
#include <array>
#include <new>
#include <limits>

#include <functional>
#include <type_traits>

namespace fakeit
{

	struct VirtualOffsetSelector
	{

		unsigned int offset;

		virtual unsigned int offset0(int)
		{
			return offset = 0;
		}

		virtual unsigned int offset1(int)
		{
			return offset = 1;
		}

		virtual unsigned int offset2(int)
		{
			return offset = 2;
		}

		virtual unsigned int offset3(int)
		{
			return offset = 3;
		}

		virtual unsigned int offset4(int)
		{
			return offset = 4;
		}

		virtual unsigned int offset5(int)
		{
			return offset = 5;
		}

		virtual unsigned int offset6(int)
		{
			return offset = 6;
		}

		virtual unsigned int offset7(int)
		{
			return offset = 7;
		}

		virtual unsigned int offset8(int)
		{
			return offset = 8;
		}

		virtual unsigned int offset9(int)
		{
			return offset = 9;
		}

		virtual unsigned int offset10(int)
		{
			return offset = 10;
		}

		virtual unsigned int offset11(int)
		{
			return offset = 11;
		}

		virtual unsigned int offset12(int)
		{
			return offset = 12;
		}

		virtual unsigned int offset13(int)
		{
			return offset = 13;
		}

		virtual unsigned int offset14(int)
		{
			return offset = 14;
		}

		virtual unsigned int offset15(int)
		{
			return offset = 15;
		}

		virtual unsigned int offset16(int)
		{
			return offset = 16;
		}

		virtual unsigned int offset17(int)
		{
			return offset = 17;
		}

		virtual unsigned int offset18(int)
		{
			return offset = 18;
		}

		virtual unsigned int offset19(int)
		{
			return offset = 19;
		}

		virtual unsigned int offset20(int)
		{
			return offset = 20;
		}

		virtual unsigned int offset21(int)
		{
			return offset = 21;
		}

		virtual unsigned int offset22(int)
		{
			return offset = 22;
		}

		virtual unsigned int offset23(int)
		{
			return offset = 23;
		}

		virtual unsigned int offset24(int)
		{
			return offset = 24;
		}

		virtual unsigned int offset25(int)
		{
			return offset = 25;
		}

		virtual unsigned int offset26(int)
		{
			return offset = 26;
		}

		virtual unsigned int offset27(int)
		{
			return offset = 27;
		}

		virtual unsigned int offset28(int)
		{
			return offset = 28;
		}

		virtual unsigned int offset29(int)
		{
			return offset = 29;
		}

		virtual unsigned int offset30(int)
		{
			return offset = 30;
		}

		virtual unsigned int offset31(int)
		{
			return offset = 31;
		}

		virtual unsigned int offset32(int)
		{
			return offset = 32;
		}

		virtual unsigned int offset33(int)
		{
			return offset = 33;
		}

		virtual unsigned int offset34(int)
		{
			return offset = 34;
		}

		virtual unsigned int offset35(int)
		{
			return offset = 35;
		}

		virtual unsigned int offset36(int)
		{
			return offset = 36;
		}

		virtual unsigned int offset37(int)
		{
			return offset = 37;
		}

		virtual unsigned int offset38(int)
		{
			return offset = 38;
		}

		virtual unsigned int offset39(int)
		{
			return offset = 39;
		}

		virtual unsigned int offset40(int)
		{
			return offset = 40;
		}

		virtual unsigned int offset41(int)
		{
			return offset = 41;
		}

		virtual unsigned int offset42(int)
		{
			return offset = 42;
		}

		virtual unsigned int offset43(int)
		{
			return offset = 43;
		}

		virtual unsigned int offset44(int)
		{
			return offset = 44;
		}

		virtual unsigned int offset45(int)
		{
			return offset = 45;
		}

		virtual unsigned int offset46(int)
		{
			return offset = 46;
		}

		virtual unsigned int offset47(int)
		{
			return offset = 47;
		}

		virtual unsigned int offset48(int)
		{
			return offset = 48;
		}

		virtual unsigned int offset49(int)
		{
			return offset = 49;
		}

		virtual unsigned int offset50(int)
		{
			return offset = 50;
		}

		virtual unsigned int offset51(int)
		{
			return offset = 51;
		}

		virtual unsigned int offset52(int)
		{
			return offset = 52;
		}

		virtual unsigned int offset53(int)
		{
			return offset = 53;
		}

		virtual unsigned int offset54(int)
		{
			return offset = 54;
		}

		virtual unsigned int offset55(int)
		{
			return offset = 55;
		}

		virtual unsigned int offset56(int)
		{
			return offset = 56;
		}

		virtual unsigned int offset57(int)
		{
			return offset = 57;
		}

		virtual unsigned int offset58(int)
		{
			return offset = 58;
		}

		virtual unsigned int offset59(int)
		{
			return offset = 59;
		}

		virtual unsigned int offset60(int)
		{
			return offset = 60;
		}

		virtual unsigned int offset61(int)
		{
			return offset = 61;
		}

		virtual unsigned int offset62(int)
		{
			return offset = 62;
		}

		virtual unsigned int offset63(int)
		{
			return offset = 63;
		}

		virtual unsigned int offset64(int)
		{
			return offset = 64;
		}

		virtual unsigned int offset65(int)
		{
			return offset = 65;
		}

		virtual unsigned int offset66(int)
		{
			return offset = 66;
		}

		virtual unsigned int offset67(int)
		{
			return offset = 67;
		}

		virtual unsigned int offset68(int)
		{
			return offset = 68;
		}

		virtual unsigned int offset69(int)
		{
			return offset = 69;
		}

		virtual unsigned int offset70(int)
		{
			return offset = 70;
		}

		virtual unsigned int offset71(int)
		{
			return offset = 71;
		}

		virtual unsigned int offset72(int)
		{
			return offset = 72;
		}

		virtual unsigned int offset73(int)
		{
			return offset = 73;
		}

		virtual unsigned int offset74(int)
		{
			return offset = 74;
		}

		virtual unsigned int offset75(int)
		{
			return offset = 75;
		}

		virtual unsigned int offset76(int)
		{
			return offset = 76;
		}

		virtual unsigned int offset77(int)
		{
			return offset = 77;
		}

		virtual unsigned int offset78(int)
		{
			return offset = 78;
		}

		virtual unsigned int offset79(int)
		{
			return offset = 79;
		}

		virtual unsigned int offset80(int)
		{
			return offset = 80;
		}

		virtual unsigned int offset81(int)
		{
			return offset = 81;
		}

		virtual unsigned int offset82(int)
		{
			return offset = 82;
		}

		virtual unsigned int offset83(int)
		{
			return offset = 83;
		}

		virtual unsigned int offset84(int)
		{
			return offset = 84;
		}

		virtual unsigned int offset85(int)
		{
			return offset = 85;
		}

		virtual unsigned int offset86(int)
		{
			return offset = 86;
		}

		virtual unsigned int offset87(int)
		{
			return offset = 87;
		}

		virtual unsigned int offset88(int)
		{
			return offset = 88;
		}

		virtual unsigned int offset89(int)
		{
			return offset = 89;
		}

		virtual unsigned int offset90(int)
		{
			return offset = 90;
		}

		virtual unsigned int offset91(int)
		{
			return offset = 91;
		}

		virtual unsigned int offset92(int)
		{
			return offset = 92;
		}

		virtual unsigned int offset93(int)
		{
			return offset = 93;
		}

		virtual unsigned int offset94(int)
		{
			return offset = 94;
		}

		virtual unsigned int offset95(int)
		{
			return offset = 95;
		}

		virtual unsigned int offset96(int)
		{
			return offset = 96;
		}

		virtual unsigned int offset97(int)
		{
			return offset = 97;
		}

		virtual unsigned int offset98(int)
		{
			return offset = 98;
		}

		virtual unsigned int offset99(int)
		{
			return offset = 99;
		}

		virtual unsigned int offset100(int)
		{
			return offset = 100;
		}

		virtual unsigned int offset101(int)
		{
			return offset = 101;
		}

		virtual unsigned int offset102(int)
		{
			return offset = 102;
		}

		virtual unsigned int offset103(int)
		{
			return offset = 103;
		}

		virtual unsigned int offset104(int)
		{
			return offset = 104;
		}

		virtual unsigned int offset105(int)
		{
			return offset = 105;
		}

		virtual unsigned int offset106(int)
		{
			return offset = 106;
		}

		virtual unsigned int offset107(int)
		{
			return offset = 107;
		}

		virtual unsigned int offset108(int)
		{
			return offset = 108;
		}

		virtual unsigned int offset109(int)
		{
			return offset = 109;
		}

		virtual unsigned int offset110(int)
		{
			return offset = 110;
		}

		virtual unsigned int offset111(int)
		{
			return offset = 111;
		}

		virtual unsigned int offset112(int)
		{
			return offset = 112;
		}

		virtual unsigned int offset113(int)
		{
			return offset = 113;
		}

		virtual unsigned int offset114(int)
		{
			return offset = 114;
		}

		virtual unsigned int offset115(int)
		{
			return offset = 115;
		}

		virtual unsigned int offset116(int)
		{
			return offset = 116;
		}

		virtual unsigned int offset117(int)
		{
			return offset = 117;
		}

		virtual unsigned int offset118(int)
		{
			return offset = 118;
		}

		virtual unsigned int offset119(int)
		{
			return offset = 119;
		}

		virtual unsigned int offset120(int)
		{
			return offset = 120;
		}

		virtual unsigned int offset121(int)
		{
			return offset = 121;
		}

		virtual unsigned int offset122(int)
		{
			return offset = 122;
		}

		virtual unsigned int offset123(int)
		{
			return offset = 123;
		}

		virtual unsigned int offset124(int)
		{
			return offset = 124;
		}

		virtual unsigned int offset125(int)
		{
			return offset = 125;
		}

		virtual unsigned int offset126(int)
		{
			return offset = 126;
		}

		virtual unsigned int offset127(int)
		{
			return offset = 127;
		}

		virtual unsigned int offset128(int)
		{
			return offset = 128;
		}

		virtual unsigned int offset129(int)
		{
			return offset = 129;
		}

		virtual unsigned int offset130(int)
		{
			return offset = 130;
		}

		virtual unsigned int offset131(int)
		{
			return offset = 131;
		}

		virtual unsigned int offset132(int)
		{
			return offset = 132;
		}

		virtual unsigned int offset133(int)
		{
			return offset = 133;
		}

		virtual unsigned int offset134(int)
		{
			return offset = 134;
		}

		virtual unsigned int offset135(int)
		{
			return offset = 135;
		}

		virtual unsigned int offset136(int)
		{
			return offset = 136;
		}

		virtual unsigned int offset137(int)
		{
			return offset = 137;
		}

		virtual unsigned int offset138(int)
		{
			return offset = 138;
		}

		virtual unsigned int offset139(int)
		{
			return offset = 139;
		}

		virtual unsigned int offset140(int)
		{
			return offset = 140;
		}

		virtual unsigned int offset141(int)
		{
			return offset = 141;
		}

		virtual unsigned int offset142(int)
		{
			return offset = 142;
		}

		virtual unsigned int offset143(int)
		{
			return offset = 143;
		}

		virtual unsigned int offset144(int)
		{
			return offset = 144;
		}

		virtual unsigned int offset145(int)
		{
			return offset = 145;
		}

		virtual unsigned int offset146(int)
		{
			return offset = 146;
		}

		virtual unsigned int offset147(int)
		{
			return offset = 147;
		}

		virtual unsigned int offset148(int)
		{
			return offset = 148;
		}

		virtual unsigned int offset149(int)
		{
			return offset = 149;
		}

		virtual unsigned int offset150(int)
		{
			return offset = 150;
		}

		virtual unsigned int offset151(int)
		{
			return offset = 151;
		}

		virtual unsigned int offset152(int)
		{
			return offset = 152;
		}

		virtual unsigned int offset153(int)
		{
			return offset = 153;
		}

		virtual unsigned int offset154(int)
		{
			return offset = 154;
		}

		virtual unsigned int offset155(int)
		{
			return offset = 155;
		}

		virtual unsigned int offset156(int)
		{
			return offset = 156;
		}

		virtual unsigned int offset157(int)
		{
			return offset = 157;
		}

		virtual unsigned int offset158(int)
		{
			return offset = 158;
		}

		virtual unsigned int offset159(int)
		{
			return offset = 159;
		}

		virtual unsigned int offset160(int)
		{
			return offset = 160;
		}

		virtual unsigned int offset161(int)
		{
			return offset = 161;
		}

		virtual unsigned int offset162(int)
		{
			return offset = 162;
		}

		virtual unsigned int offset163(int)
		{
			return offset = 163;
		}

		virtual unsigned int offset164(int)
		{
			return offset = 164;
		}

		virtual unsigned int offset165(int)
		{
			return offset = 165;
		}

		virtual unsigned int offset166(int)
		{
			return offset = 166;
		}

		virtual unsigned int offset167(int)
		{
			return offset = 167;
		}

		virtual unsigned int offset168(int)
		{
			return offset = 168;
		}

		virtual unsigned int offset169(int)
		{
			return offset = 169;
		}

		virtual unsigned int offset170(int)
		{
			return offset = 170;
		}

		virtual unsigned int offset171(int)
		{
			return offset = 171;
		}

		virtual unsigned int offset172(int)
		{
			return offset = 172;
		}

		virtual unsigned int offset173(int)
		{
			return offset = 173;
		}

		virtual unsigned int offset174(int)
		{
			return offset = 174;
		}

		virtual unsigned int offset175(int)
		{
			return offset = 175;
		}

		virtual unsigned int offset176(int)
		{
			return offset = 176;
		}

		virtual unsigned int offset177(int)
		{
			return offset = 177;
		}

		virtual unsigned int offset178(int)
		{
			return offset = 178;
		}

		virtual unsigned int offset179(int)
		{
			return offset = 179;
		}

		virtual unsigned int offset180(int)
		{
			return offset = 180;
		}

		virtual unsigned int offset181(int)
		{
			return offset = 181;
		}

		virtual unsigned int offset182(int)
		{
			return offset = 182;
		}

		virtual unsigned int offset183(int)
		{
			return offset = 183;
		}

		virtual unsigned int offset184(int)
		{
			return offset = 184;
		}

		virtual unsigned int offset185(int)
		{
			return offset = 185;
		}

		virtual unsigned int offset186(int)
		{
			return offset = 186;
		}

		virtual unsigned int offset187(int)
		{
			return offset = 187;
		}

		virtual unsigned int offset188(int)
		{
			return offset = 188;
		}

		virtual unsigned int offset189(int)
		{
			return offset = 189;
		}

		virtual unsigned int offset190(int)
		{
			return offset = 190;
		}

		virtual unsigned int offset191(int)
		{
			return offset = 191;
		}

		virtual unsigned int offset192(int)
		{
			return offset = 192;
		}

		virtual unsigned int offset193(int)
		{
			return offset = 193;
		}

		virtual unsigned int offset194(int)
		{
			return offset = 194;
		}

		virtual unsigned int offset195(int)
		{
			return offset = 195;
		}

		virtual unsigned int offset196(int)
		{
			return offset = 196;
		}

		virtual unsigned int offset197(int)
		{
			return offset = 197;
		}

		virtual unsigned int offset198(int)
		{
			return offset = 198;
		}

		virtual unsigned int offset199(int)
		{
			return offset = 199;
		}


		virtual unsigned int offset200(int)
		{
			return offset = 200;
		}

		virtual unsigned int offset201(int)
		{
			return offset = 201;
		}

		virtual unsigned int offset202(int)
		{
			return offset = 202;
		}

		virtual unsigned int offset203(int)
		{
			return offset = 203;
		}

		virtual unsigned int offset204(int)
		{
			return offset = 204;
		}

		virtual unsigned int offset205(int)
		{
			return offset = 205;
		}

		virtual unsigned int offset206(int)
		{
			return offset = 206;
		}

		virtual unsigned int offset207(int)
		{
			return offset = 207;
		}

		virtual unsigned int offset208(int)
		{
			return offset = 208;
		}

		virtual unsigned int offset209(int)
		{
			return offset = 209;
		}

		virtual unsigned int offset210(int)
		{
			return offset = 210;
		}

		virtual unsigned int offset211(int)
		{
			return offset = 211;
		}

		virtual unsigned int offset212(int)
		{
			return offset = 212;
		}

		virtual unsigned int offset213(int)
		{
			return offset = 213;
		}

		virtual unsigned int offset214(int)
		{
			return offset = 214;
		}

		virtual unsigned int offset215(int)
		{
			return offset = 215;
		}

		virtual unsigned int offset216(int)
		{
			return offset = 216;
		}

		virtual unsigned int offset217(int)
		{
			return offset = 217;
		}

		virtual unsigned int offset218(int)
		{
			return offset = 218;
		}

		virtual unsigned int offset219(int)
		{
			return offset = 219;
		}

		virtual unsigned int offset220(int)
		{
			return offset = 220;
		}

		virtual unsigned int offset221(int)
		{
			return offset = 221;
		}

		virtual unsigned int offset222(int)
		{
			return offset = 222;
		}

		virtual unsigned int offset223(int)
		{
			return offset = 223;
		}

		virtual unsigned int offset224(int)
		{
			return offset = 224;
		}

		virtual unsigned int offset225(int)
		{
			return offset = 225;
		}

		virtual unsigned int offset226(int)
		{
			return offset = 226;
		}

		virtual unsigned int offset227(int)
		{
			return offset = 227;
		}

		virtual unsigned int offset228(int)
		{
			return offset = 228;
		}

		virtual unsigned int offset229(int)
		{
			return offset = 229;
		}

		virtual unsigned int offset230(int)
		{
			return offset = 230;
		}

		virtual unsigned int offset231(int)
		{
			return offset = 231;
		}

		virtual unsigned int offset232(int)
		{
			return offset = 232;
		}

		virtual unsigned int offset233(int)
		{
			return offset = 233;
		}

		virtual unsigned int offset234(int)
		{
			return offset = 234;
		}

		virtual unsigned int offset235(int)
		{
			return offset = 235;
		}

		virtual unsigned int offset236(int)
		{
			return offset = 236;
		}

		virtual unsigned int offset237(int)
		{
			return offset = 237;
		}

		virtual unsigned int offset238(int)
		{
			return offset = 238;
		}

		virtual unsigned int offset239(int)
		{
			return offset = 239;
		}

		virtual unsigned int offset240(int)
		{
			return offset = 240;
		}

		virtual unsigned int offset241(int)
		{
			return offset = 241;
		}

		virtual unsigned int offset242(int)
		{
			return offset = 242;
		}

		virtual unsigned int offset243(int)
		{
			return offset = 243;
		}

		virtual unsigned int offset244(int)
		{
			return offset = 244;
		}

		virtual unsigned int offset245(int)
		{
			return offset = 245;
		}

		virtual unsigned int offset246(int)
		{
			return offset = 246;
		}

		virtual unsigned int offset247(int)
		{
			return offset = 247;
		}

		virtual unsigned int offset248(int)
		{
			return offset = 248;
		}

		virtual unsigned int offset249(int)
		{
			return offset = 249;
		}

		virtual unsigned int offset250(int)
		{
			return offset = 250;
		}

		virtual unsigned int offset251(int)
		{
			return offset = 251;
		}

		virtual unsigned int offset252(int)
		{
			return offset = 252;
		}

		virtual unsigned int offset253(int)
		{
			return offset = 253;
		}

		virtual unsigned int offset254(int)
		{
			return offset = 254;
		}

		virtual unsigned int offset255(int)
		{
			return offset = 255;
		}

		virtual unsigned int offset256(int)
		{
			return offset = 256;
		}

		virtual unsigned int offset257(int)
		{
			return offset = 257;
		}

		virtual unsigned int offset258(int)
		{
			return offset = 258;
		}

		virtual unsigned int offset259(int)
		{
			return offset = 259;
		}

		virtual unsigned int offset260(int)
		{
			return offset = 260;
		}

		virtual unsigned int offset261(int)
		{
			return offset = 261;
		}

		virtual unsigned int offset262(int)
		{
			return offset = 262;
		}

		virtual unsigned int offset263(int)
		{
			return offset = 263;
		}

		virtual unsigned int offset264(int)
		{
			return offset = 264;
		}

		virtual unsigned int offset265(int)
		{
			return offset = 265;
		}

		virtual unsigned int offset266(int)
		{
			return offset = 266;
		}

		virtual unsigned int offset267(int)
		{
			return offset = 267;
		}

		virtual unsigned int offset268(int)
		{
			return offset = 268;
		}

		virtual unsigned int offset269(int)
		{
			return offset = 269;
		}

		virtual unsigned int offset270(int)
		{
			return offset = 270;
		}

		virtual unsigned int offset271(int)
		{
			return offset = 271;
		}

		virtual unsigned int offset272(int)
		{
			return offset = 272;
		}

		virtual unsigned int offset273(int)
		{
			return offset = 273;
		}

		virtual unsigned int offset274(int)
		{
			return offset = 274;
		}

		virtual unsigned int offset275(int)
		{
			return offset = 275;
		}

		virtual unsigned int offset276(int)
		{
			return offset = 276;
		}

		virtual unsigned int offset277(int)
		{
			return offset = 277;
		}

		virtual unsigned int offset278(int)
		{
			return offset = 278;
		}

		virtual unsigned int offset279(int)
		{
			return offset = 279;
		}

		virtual unsigned int offset280(int)
		{
			return offset = 280;
		}

		virtual unsigned int offset281(int)
		{
			return offset = 281;
		}

		virtual unsigned int offset282(int)
		{
			return offset = 282;
		}

		virtual unsigned int offset283(int)
		{
			return offset = 283;
		}

		virtual unsigned int offset284(int)
		{
			return offset = 284;
		}

		virtual unsigned int offset285(int)
		{
			return offset = 285;
		}

		virtual unsigned int offset286(int)
		{
			return offset = 286;
		}

		virtual unsigned int offset287(int)
		{
			return offset = 287;
		}

		virtual unsigned int offset288(int)
		{
			return offset = 288;
		}

		virtual unsigned int offset289(int)
		{
			return offset = 289;
		}

		virtual unsigned int offset290(int)
		{
			return offset = 290;
		}

		virtual unsigned int offset291(int)
		{
			return offset = 291;
		}

		virtual unsigned int offset292(int)
		{
			return offset = 292;
		}

		virtual unsigned int offset293(int)
		{
			return offset = 293;
		}

		virtual unsigned int offset294(int)
		{
			return offset = 294;
		}

		virtual unsigned int offset295(int)
		{
			return offset = 295;
		}

		virtual unsigned int offset296(int)
		{
			return offset = 296;
		}

		virtual unsigned int offset297(int)
		{
			return offset = 297;
		}

		virtual unsigned int offset298(int)
		{
			return offset = 298;
		}

		virtual unsigned int offset299(int)
		{
			return offset = 299;
		}


		virtual unsigned int offset300(int)
		{
			return offset = 300;
		}

		virtual unsigned int offset301(int)
		{
			return offset = 301;
		}

		virtual unsigned int offset302(int)
		{
			return offset = 302;
		}

		virtual unsigned int offset303(int)
		{
			return offset = 303;
		}

		virtual unsigned int offset304(int)
		{
			return offset = 304;
		}

		virtual unsigned int offset305(int)
		{
			return offset = 305;
		}

		virtual unsigned int offset306(int)
		{
			return offset = 306;
		}

		virtual unsigned int offset307(int)
		{
			return offset = 307;
		}

		virtual unsigned int offset308(int)
		{
			return offset = 308;
		}

		virtual unsigned int offset309(int)
		{
			return offset = 309;
		}

		virtual unsigned int offset310(int)
		{
			return offset = 310;
		}

		virtual unsigned int offset311(int)
		{
			return offset = 311;
		}

		virtual unsigned int offset312(int)
		{
			return offset = 312;
		}

		virtual unsigned int offset313(int)
		{
			return offset = 313;
		}

		virtual unsigned int offset314(int)
		{
			return offset = 314;
		}

		virtual unsigned int offset315(int)
		{
			return offset = 315;
		}

		virtual unsigned int offset316(int)
		{
			return offset = 316;
		}

		virtual unsigned int offset317(int)
		{
			return offset = 317;
		}

		virtual unsigned int offset318(int)
		{
			return offset = 318;
		}

		virtual unsigned int offset319(int)
		{
			return offset = 319;
		}

		virtual unsigned int offset320(int)
		{
			return offset = 320;
		}

		virtual unsigned int offset321(int)
		{
			return offset = 321;
		}

		virtual unsigned int offset322(int)
		{
			return offset = 322;
		}

		virtual unsigned int offset323(int)
		{
			return offset = 323;
		}

		virtual unsigned int offset324(int)
		{
			return offset = 324;
		}

		virtual unsigned int offset325(int)
		{
			return offset = 325;
		}

		virtual unsigned int offset326(int)
		{
			return offset = 326;
		}

		virtual unsigned int offset327(int)
		{
			return offset = 327;
		}

		virtual unsigned int offset328(int)
		{
			return offset = 328;
		}

		virtual unsigned int offset329(int)
		{
			return offset = 329;
		}

		virtual unsigned int offset330(int)
		{
			return offset = 330;
		}

		virtual unsigned int offset331(int)
		{
			return offset = 331;
		}

		virtual unsigned int offset332(int)
		{
			return offset = 332;
		}

		virtual unsigned int offset333(int)
		{
			return offset = 333;
		}

		virtual unsigned int offset334(int)
		{
			return offset = 334;
		}

		virtual unsigned int offset335(int)
		{
			return offset = 335;
		}

		virtual unsigned int offset336(int)
		{
			return offset = 336;
		}

		virtual unsigned int offset337(int)
		{
			return offset = 337;
		}

		virtual unsigned int offset338(int)
		{
			return offset = 338;
		}

		virtual unsigned int offset339(int)
		{
			return offset = 339;
		}

		virtual unsigned int offset340(int)
		{
			return offset = 340;
		}

		virtual unsigned int offset341(int)
		{
			return offset = 341;
		}

		virtual unsigned int offset342(int)
		{
			return offset = 342;
		}

		virtual unsigned int offset343(int)
		{
			return offset = 343;
		}

		virtual unsigned int offset344(int)
		{
			return offset = 344;
		}

		virtual unsigned int offset345(int)
		{
			return offset = 345;
		}

		virtual unsigned int offset346(int)
		{
			return offset = 346;
		}

		virtual unsigned int offset347(int)
		{
			return offset = 347;
		}

		virtual unsigned int offset348(int)
		{
			return offset = 348;
		}

		virtual unsigned int offset349(int)
		{
			return offset = 349;
		}

		virtual unsigned int offset350(int)
		{
			return offset = 350;
		}

		virtual unsigned int offset351(int)
		{
			return offset = 351;
		}

		virtual unsigned int offset352(int)
		{
			return offset = 352;
		}

		virtual unsigned int offset353(int)
		{
			return offset = 353;
		}

		virtual unsigned int offset354(int)
		{
			return offset = 354;
		}

		virtual unsigned int offset355(int)
		{
			return offset = 355;
		}

		virtual unsigned int offset356(int)
		{
			return offset = 356;
		}

		virtual unsigned int offset357(int)
		{
			return offset = 357;
		}

		virtual unsigned int offset358(int)
		{
			return offset = 358;
		}

		virtual unsigned int offset359(int)
		{
			return offset = 359;
		}

		virtual unsigned int offset360(int)
		{
			return offset = 360;
		}

		virtual unsigned int offset361(int)
		{
			return offset = 361;
		}

		virtual unsigned int offset362(int)
		{
			return offset = 362;
		}

		virtual unsigned int offset363(int)
		{
			return offset = 363;
		}

		virtual unsigned int offset364(int)
		{
			return offset = 364;
		}

		virtual unsigned int offset365(int)
		{
			return offset = 365;
		}

		virtual unsigned int offset366(int)
		{
			return offset = 366;
		}

		virtual unsigned int offset367(int)
		{
			return offset = 367;
		}

		virtual unsigned int offset368(int)
		{
			return offset = 368;
		}

		virtual unsigned int offset369(int)
		{
			return offset = 369;
		}

		virtual unsigned int offset370(int)
		{
			return offset = 370;
		}

		virtual unsigned int offset371(int)
		{
			return offset = 371;
		}

		virtual unsigned int offset372(int)
		{
			return offset = 372;
		}

		virtual unsigned int offset373(int)
		{
			return offset = 373;
		}

		virtual unsigned int offset374(int)
		{
			return offset = 374;
		}

		virtual unsigned int offset375(int)
		{
			return offset = 375;
		}

		virtual unsigned int offset376(int)
		{
			return offset = 376;
		}

		virtual unsigned int offset377(int)
		{
			return offset = 377;
		}

		virtual unsigned int offset378(int)
		{
			return offset = 378;
		}

		virtual unsigned int offset379(int)
		{
			return offset = 379;
		}

		virtual unsigned int offset380(int)
		{
			return offset = 380;
		}

		virtual unsigned int offset381(int)
		{
			return offset = 381;
		}

		virtual unsigned int offset382(int)
		{
			return offset = 382;
		}

		virtual unsigned int offset383(int)
		{
			return offset = 383;
		}

		virtual unsigned int offset384(int)
		{
			return offset = 384;
		}

		virtual unsigned int offset385(int)
		{
			return offset = 385;
		}

		virtual unsigned int offset386(int)
		{
			return offset = 386;
		}

		virtual unsigned int offset387(int)
		{
			return offset = 387;
		}

		virtual unsigned int offset388(int)
		{
			return offset = 388;
		}

		virtual unsigned int offset389(int)
		{
			return offset = 389;
		}

		virtual unsigned int offset390(int)
		{
			return offset = 390;
		}

		virtual unsigned int offset391(int)
		{
			return offset = 391;
		}

		virtual unsigned int offset392(int)
		{
			return offset = 392;
		}

		virtual unsigned int offset393(int)
		{
			return offset = 393;
		}

		virtual unsigned int offset394(int)
		{
			return offset = 394;
		}

		virtual unsigned int offset395(int)
		{
			return offset = 395;
		}

		virtual unsigned int offset396(int)
		{
			return offset = 396;
		}

		virtual unsigned int offset397(int)
		{
			return offset = 397;
		}

		virtual unsigned int offset398(int)
		{
			return offset = 398;
		}

		virtual unsigned int offset399(int)
		{
			return offset = 399;
		}


		virtual unsigned int offset400(int)
		{
			return offset = 400;
		}

		virtual unsigned int offset401(int)
		{
			return offset = 401;
		}

		virtual unsigned int offset402(int)
		{
			return offset = 402;
		}

		virtual unsigned int offset403(int)
		{
			return offset = 403;
		}

		virtual unsigned int offset404(int)
		{
			return offset = 404;
		}

		virtual unsigned int offset405(int)
		{
			return offset = 405;
		}

		virtual unsigned int offset406(int)
		{
			return offset = 406;
		}

		virtual unsigned int offset407(int)
		{
			return offset = 407;
		}

		virtual unsigned int offset408(int)
		{
			return offset = 408;
		}

		virtual unsigned int offset409(int)
		{
			return offset = 409;
		}

		virtual unsigned int offset410(int)
		{
			return offset = 410;
		}

		virtual unsigned int offset411(int)
		{
			return offset = 411;
		}

		virtual unsigned int offset412(int)
		{
			return offset = 412;
		}

		virtual unsigned int offset413(int)
		{
			return offset = 413;
		}

		virtual unsigned int offset414(int)
		{
			return offset = 414;
		}

		virtual unsigned int offset415(int)
		{
			return offset = 415;
		}

		virtual unsigned int offset416(int)
		{
			return offset = 416;
		}

		virtual unsigned int offset417(int)
		{
			return offset = 417;
		}

		virtual unsigned int offset418(int)
		{
			return offset = 418;
		}

		virtual unsigned int offset419(int)
		{
			return offset = 419;
		}

		virtual unsigned int offset420(int)
		{
			return offset = 420;
		}

		virtual unsigned int offset421(int)
		{
			return offset = 421;
		}

		virtual unsigned int offset422(int)
		{
			return offset = 422;
		}

		virtual unsigned int offset423(int)
		{
			return offset = 423;
		}

		virtual unsigned int offset424(int)
		{
			return offset = 424;
		}

		virtual unsigned int offset425(int)
		{
			return offset = 425;
		}

		virtual unsigned int offset426(int)
		{
			return offset = 426;
		}

		virtual unsigned int offset427(int)
		{
			return offset = 427;
		}

		virtual unsigned int offset428(int)
		{
			return offset = 428;
		}

		virtual unsigned int offset429(int)
		{
			return offset = 429;
		}

		virtual unsigned int offset430(int)
		{
			return offset = 430;
		}

		virtual unsigned int offset431(int)
		{
			return offset = 431;
		}

		virtual unsigned int offset432(int)
		{
			return offset = 432;
		}

		virtual unsigned int offset433(int)
		{
			return offset = 433;
		}

		virtual unsigned int offset434(int)
		{
			return offset = 434;
		}

		virtual unsigned int offset435(int)
		{
			return offset = 435;
		}

		virtual unsigned int offset436(int)
		{
			return offset = 436;
		}

		virtual unsigned int offset437(int)
		{
			return offset = 437;
		}

		virtual unsigned int offset438(int)
		{
			return offset = 438;
		}

		virtual unsigned int offset439(int)
		{
			return offset = 439;
		}

		virtual unsigned int offset440(int)
		{
			return offset = 440;
		}

		virtual unsigned int offset441(int)
		{
			return offset = 441;
		}

		virtual unsigned int offset442(int)
		{
			return offset = 442;
		}

		virtual unsigned int offset443(int)
		{
			return offset = 443;
		}

		virtual unsigned int offset444(int)
		{
			return offset = 444;
		}

		virtual unsigned int offset445(int)
		{
			return offset = 445;
		}

		virtual unsigned int offset446(int)
		{
			return offset = 446;
		}

		virtual unsigned int offset447(int)
		{
			return offset = 447;
		}

		virtual unsigned int offset448(int)
		{
			return offset = 448;
		}

		virtual unsigned int offset449(int)
		{
			return offset = 449;
		}

		virtual unsigned int offset450(int)
		{
			return offset = 450;
		}

		virtual unsigned int offset451(int)
		{
			return offset = 451;
		}

		virtual unsigned int offset452(int)
		{
			return offset = 452;
		}

		virtual unsigned int offset453(int)
		{
			return offset = 453;
		}

		virtual unsigned int offset454(int)
		{
			return offset = 454;
		}

		virtual unsigned int offset455(int)
		{
			return offset = 455;
		}

		virtual unsigned int offset456(int)
		{
			return offset = 456;
		}

		virtual unsigned int offset457(int)
		{
			return offset = 457;
		}

		virtual unsigned int offset458(int)
		{
			return offset = 458;
		}

		virtual unsigned int offset459(int)
		{
			return offset = 459;
		}

		virtual unsigned int offset460(int)
		{
			return offset = 460;
		}

		virtual unsigned int offset461(int)
		{
			return offset = 461;
		}

		virtual unsigned int offset462(int)
		{
			return offset = 462;
		}

		virtual unsigned int offset463(int)
		{
			return offset = 463;
		}

		virtual unsigned int offset464(int)
		{
			return offset = 464;
		}

		virtual unsigned int offset465(int)
		{
			return offset = 465;
		}

		virtual unsigned int offset466(int)
		{
			return offset = 466;
		}

		virtual unsigned int offset467(int)
		{
			return offset = 467;
		}

		virtual unsigned int offset468(int)
		{
			return offset = 468;
		}

		virtual unsigned int offset469(int)
		{
			return offset = 469;
		}

		virtual unsigned int offset470(int)
		{
			return offset = 470;
		}

		virtual unsigned int offset471(int)
		{
			return offset = 471;
		}

		virtual unsigned int offset472(int)
		{
			return offset = 472;
		}

		virtual unsigned int offset473(int)
		{
			return offset = 473;
		}

		virtual unsigned int offset474(int)
		{
			return offset = 474;
		}

		virtual unsigned int offset475(int)
		{
			return offset = 475;
		}

		virtual unsigned int offset476(int)
		{
			return offset = 476;
		}

		virtual unsigned int offset477(int)
		{
			return offset = 477;
		}

		virtual unsigned int offset478(int)
		{
			return offset = 478;
		}

		virtual unsigned int offset479(int)
		{
			return offset = 479;
		}

		virtual unsigned int offset480(int)
		{
			return offset = 480;
		}

		virtual unsigned int offset481(int)
		{
			return offset = 481;
		}

		virtual unsigned int offset482(int)
		{
			return offset = 482;
		}

		virtual unsigned int offset483(int)
		{
			return offset = 483;
		}

		virtual unsigned int offset484(int)
		{
			return offset = 484;
		}

		virtual unsigned int offset485(int)
		{
			return offset = 485;
		}

		virtual unsigned int offset486(int)
		{
			return offset = 486;
		}

		virtual unsigned int offset487(int)
		{
			return offset = 487;
		}

		virtual unsigned int offset488(int)
		{
			return offset = 488;
		}

		virtual unsigned int offset489(int)
		{
			return offset = 489;
		}

		virtual unsigned int offset490(int)
		{
			return offset = 490;
		}

		virtual unsigned int offset491(int)
		{
			return offset = 491;
		}

		virtual unsigned int offset492(int)
		{
			return offset = 492;
		}

		virtual unsigned int offset493(int)
		{
			return offset = 493;
		}

		virtual unsigned int offset494(int)
		{
			return offset = 494;
		}

		virtual unsigned int offset495(int)
		{
			return offset = 495;
		}

		virtual unsigned int offset496(int)
		{
			return offset = 496;
		}

		virtual unsigned int offset497(int)
		{
			return offset = 497;
		}

		virtual unsigned int offset498(int)
		{
			return offset = 498;
		}

		virtual unsigned int offset499(int)
		{
			return offset = 499;
		}


		virtual unsigned int offset500(int)
		{
			return offset = 500;
		}

		virtual unsigned int offset501(int)
		{
			return offset = 501;
		}

		virtual unsigned int offset502(int)
		{
			return offset = 502;
		}

		virtual unsigned int offset503(int)
		{
			return offset = 503;
		}

		virtual unsigned int offset504(int)
		{
			return offset = 504;
		}

		virtual unsigned int offset505(int)
		{
			return offset = 505;
		}

		virtual unsigned int offset506(int)
		{
			return offset = 506;
		}

		virtual unsigned int offset507(int)
		{
			return offset = 507;
		}

		virtual unsigned int offset508(int)
		{
			return offset = 508;
		}

		virtual unsigned int offset509(int)
		{
			return offset = 509;
		}

		virtual unsigned int offset510(int)
		{
			return offset = 510;
		}

		virtual unsigned int offset511(int)
		{
			return offset = 511;
		}

		virtual unsigned int offset512(int)
		{
			return offset = 512;
		}

		virtual unsigned int offset513(int)
		{
			return offset = 513;
		}

		virtual unsigned int offset514(int)
		{
			return offset = 514;
		}

		virtual unsigned int offset515(int)
		{
			return offset = 515;
		}

		virtual unsigned int offset516(int)
		{
			return offset = 516;
		}

		virtual unsigned int offset517(int)
		{
			return offset = 517;
		}

		virtual unsigned int offset518(int)
		{
			return offset = 518;
		}

		virtual unsigned int offset519(int)
		{
			return offset = 519;
		}

		virtual unsigned int offset520(int)
		{
			return offset = 520;
		}

		virtual unsigned int offset521(int)
		{
			return offset = 521;
		}

		virtual unsigned int offset522(int)
		{
			return offset = 522;
		}

		virtual unsigned int offset523(int)
		{
			return offset = 523;
		}

		virtual unsigned int offset524(int)
		{
			return offset = 524;
		}

		virtual unsigned int offset525(int)
		{
			return offset = 525;
		}

		virtual unsigned int offset526(int)
		{
			return offset = 526;
		}

		virtual unsigned int offset527(int)
		{
			return offset = 527;
		}

		virtual unsigned int offset528(int)
		{
			return offset = 528;
		}

		virtual unsigned int offset529(int)
		{
			return offset = 529;
		}

		virtual unsigned int offset530(int)
		{
			return offset = 530;
		}

		virtual unsigned int offset531(int)
		{
			return offset = 531;
		}

		virtual unsigned int offset532(int)
		{
			return offset = 532;
		}

		virtual unsigned int offset533(int)
		{
			return offset = 533;
		}

		virtual unsigned int offset534(int)
		{
			return offset = 534;
		}

		virtual unsigned int offset535(int)
		{
			return offset = 535;
		}

		virtual unsigned int offset536(int)
		{
			return offset = 536;
		}

		virtual unsigned int offset537(int)
		{
			return offset = 537;
		}

		virtual unsigned int offset538(int)
		{
			return offset = 538;
		}

		virtual unsigned int offset539(int)
		{
			return offset = 539;
		}

		virtual unsigned int offset540(int)
		{
			return offset = 540;
		}

		virtual unsigned int offset541(int)
		{
			return offset = 541;
		}

		virtual unsigned int offset542(int)
		{
			return offset = 542;
		}

		virtual unsigned int offset543(int)
		{
			return offset = 543;
		}

		virtual unsigned int offset544(int)
		{
			return offset = 544;
		}

		virtual unsigned int offset545(int)
		{
			return offset = 545;
		}

		virtual unsigned int offset546(int)
		{
			return offset = 546;
		}

		virtual unsigned int offset547(int)
		{
			return offset = 547;
		}

		virtual unsigned int offset548(int)
		{
			return offset = 548;
		}

		virtual unsigned int offset549(int)
		{
			return offset = 549;
		}

		virtual unsigned int offset550(int)
		{
			return offset = 550;
		}

		virtual unsigned int offset551(int)
		{
			return offset = 551;
		}

		virtual unsigned int offset552(int)
		{
			return offset = 552;
		}

		virtual unsigned int offset553(int)
		{
			return offset = 553;
		}

		virtual unsigned int offset554(int)
		{
			return offset = 554;
		}

		virtual unsigned int offset555(int)
		{
			return offset = 555;
		}

		virtual unsigned int offset556(int)
		{
			return offset = 556;
		}

		virtual unsigned int offset557(int)
		{
			return offset = 557;
		}

		virtual unsigned int offset558(int)
		{
			return offset = 558;
		}

		virtual unsigned int offset559(int)
		{
			return offset = 559;
		}

		virtual unsigned int offset560(int)
		{
			return offset = 560;
		}

		virtual unsigned int offset561(int)
		{
			return offset = 561;
		}

		virtual unsigned int offset562(int)
		{
			return offset = 562;
		}

		virtual unsigned int offset563(int)
		{
			return offset = 563;
		}

		virtual unsigned int offset564(int)
		{
			return offset = 564;
		}

		virtual unsigned int offset565(int)
		{
			return offset = 565;
		}

		virtual unsigned int offset566(int)
		{
			return offset = 566;
		}

		virtual unsigned int offset567(int)
		{
			return offset = 567;
		}

		virtual unsigned int offset568(int)
		{
			return offset = 568;
		}

		virtual unsigned int offset569(int)
		{
			return offset = 569;
		}

		virtual unsigned int offset570(int)
		{
			return offset = 570;
		}

		virtual unsigned int offset571(int)
		{
			return offset = 571;
		}

		virtual unsigned int offset572(int)
		{
			return offset = 572;
		}

		virtual unsigned int offset573(int)
		{
			return offset = 573;
		}

		virtual unsigned int offset574(int)
		{
			return offset = 574;
		}

		virtual unsigned int offset575(int)
		{
			return offset = 575;
		}

		virtual unsigned int offset576(int)
		{
			return offset = 576;
		}

		virtual unsigned int offset577(int)
		{
			return offset = 577;
		}

		virtual unsigned int offset578(int)
		{
			return offset = 578;
		}

		virtual unsigned int offset579(int)
		{
			return offset = 579;
		}

		virtual unsigned int offset580(int)
		{
			return offset = 580;
		}

		virtual unsigned int offset581(int)
		{
			return offset = 581;
		}

		virtual unsigned int offset582(int)
		{
			return offset = 582;
		}

		virtual unsigned int offset583(int)
		{
			return offset = 583;
		}

		virtual unsigned int offset584(int)
		{
			return offset = 584;
		}

		virtual unsigned int offset585(int)
		{
			return offset = 585;
		}

		virtual unsigned int offset586(int)
		{
			return offset = 586;
		}

		virtual unsigned int offset587(int)
		{
			return offset = 587;
		}

		virtual unsigned int offset588(int)
		{
			return offset = 588;
		}

		virtual unsigned int offset589(int)
		{
			return offset = 589;
		}

		virtual unsigned int offset590(int)
		{
			return offset = 590;
		}

		virtual unsigned int offset591(int)
		{
			return offset = 591;
		}

		virtual unsigned int offset592(int)
		{
			return offset = 592;
		}

		virtual unsigned int offset593(int)
		{
			return offset = 593;
		}

		virtual unsigned int offset594(int)
		{
			return offset = 594;
		}

		virtual unsigned int offset595(int)
		{
			return offset = 595;
		}

		virtual unsigned int offset596(int)
		{
			return offset = 596;
		}

		virtual unsigned int offset597(int)
		{
			return offset = 597;
		}

		virtual unsigned int offset598(int)
		{
			return offset = 598;
		}

		virtual unsigned int offset599(int)
		{
			return offset = 599;
		}


		virtual unsigned int offset600(int)
		{
			return offset = 600;
		}

		virtual unsigned int offset601(int)
		{
			return offset = 601;
		}

		virtual unsigned int offset602(int)
		{
			return offset = 602;
		}

		virtual unsigned int offset603(int)
		{
			return offset = 603;
		}

		virtual unsigned int offset604(int)
		{
			return offset = 604;
		}

		virtual unsigned int offset605(int)
		{
			return offset = 605;
		}

		virtual unsigned int offset606(int)
		{
			return offset = 606;
		}

		virtual unsigned int offset607(int)
		{
			return offset = 607;
		}

		virtual unsigned int offset608(int)
		{
			return offset = 608;
		}

		virtual unsigned int offset609(int)
		{
			return offset = 609;
		}

		virtual unsigned int offset610(int)
		{
			return offset = 610;
		}

		virtual unsigned int offset611(int)
		{
			return offset = 611;
		}

		virtual unsigned int offset612(int)
		{
			return offset = 612;
		}

		virtual unsigned int offset613(int)
		{
			return offset = 613;
		}

		virtual unsigned int offset614(int)
		{
			return offset = 614;
		}

		virtual unsigned int offset615(int)
		{
			return offset = 615;
		}

		virtual unsigned int offset616(int)
		{
			return offset = 616;
		}

		virtual unsigned int offset617(int)
		{
			return offset = 617;
		}

		virtual unsigned int offset618(int)
		{
			return offset = 618;
		}

		virtual unsigned int offset619(int)
		{
			return offset = 619;
		}

		virtual unsigned int offset620(int)
		{
			return offset = 620;
		}

		virtual unsigned int offset621(int)
		{
			return offset = 621;
		}

		virtual unsigned int offset622(int)
		{
			return offset = 622;
		}

		virtual unsigned int offset623(int)
		{
			return offset = 623;
		}

		virtual unsigned int offset624(int)
		{
			return offset = 624;
		}

		virtual unsigned int offset625(int)
		{
			return offset = 625;
		}

		virtual unsigned int offset626(int)
		{
			return offset = 626;
		}

		virtual unsigned int offset627(int)
		{
			return offset = 627;
		}

		virtual unsigned int offset628(int)
		{
			return offset = 628;
		}

		virtual unsigned int offset629(int)
		{
			return offset = 629;
		}

		virtual unsigned int offset630(int)
		{
			return offset = 630;
		}

		virtual unsigned int offset631(int)
		{
			return offset = 631;
		}

		virtual unsigned int offset632(int)
		{
			return offset = 632;
		}

		virtual unsigned int offset633(int)
		{
			return offset = 633;
		}

		virtual unsigned int offset634(int)
		{
			return offset = 634;
		}

		virtual unsigned int offset635(int)
		{
			return offset = 635;
		}

		virtual unsigned int offset636(int)
		{
			return offset = 636;
		}

		virtual unsigned int offset637(int)
		{
			return offset = 637;
		}

		virtual unsigned int offset638(int)
		{
			return offset = 638;
		}

		virtual unsigned int offset639(int)
		{
			return offset = 639;
		}

		virtual unsigned int offset640(int)
		{
			return offset = 640;
		}

		virtual unsigned int offset641(int)
		{
			return offset = 641;
		}

		virtual unsigned int offset642(int)
		{
			return offset = 642;
		}

		virtual unsigned int offset643(int)
		{
			return offset = 643;
		}

		virtual unsigned int offset644(int)
		{
			return offset = 644;
		}

		virtual unsigned int offset645(int)
		{
			return offset = 645;
		}

		virtual unsigned int offset646(int)
		{
			return offset = 646;
		}

		virtual unsigned int offset647(int)
		{
			return offset = 647;
		}

		virtual unsigned int offset648(int)
		{
			return offset = 648;
		}

		virtual unsigned int offset649(int)
		{
			return offset = 649;
		}

		virtual unsigned int offset650(int)
		{
			return offset = 650;
		}

		virtual unsigned int offset651(int)
		{
			return offset = 651;
		}

		virtual unsigned int offset652(int)
		{
			return offset = 652;
		}

		virtual unsigned int offset653(int)
		{
			return offset = 653;
		}

		virtual unsigned int offset654(int)
		{
			return offset = 654;
		}

		virtual unsigned int offset655(int)
		{
			return offset = 655;
		}

		virtual unsigned int offset656(int)
		{
			return offset = 656;
		}

		virtual unsigned int offset657(int)
		{
			return offset = 657;
		}

		virtual unsigned int offset658(int)
		{
			return offset = 658;
		}

		virtual unsigned int offset659(int)
		{
			return offset = 659;
		}

		virtual unsigned int offset660(int)
		{
			return offset = 660;
		}

		virtual unsigned int offset661(int)
		{
			return offset = 661;
		}

		virtual unsigned int offset662(int)
		{
			return offset = 662;
		}

		virtual unsigned int offset663(int)
		{
			return offset = 663;
		}

		virtual unsigned int offset664(int)
		{
			return offset = 664;
		}

		virtual unsigned int offset665(int)
		{
			return offset = 665;
		}

		virtual unsigned int offset666(int)
		{
			return offset = 666;
		}

		virtual unsigned int offset667(int)
		{
			return offset = 667;
		}

		virtual unsigned int offset668(int)
		{
			return offset = 668;
		}

		virtual unsigned int offset669(int)
		{
			return offset = 669;
		}

		virtual unsigned int offset670(int)
		{
			return offset = 670;
		}

		virtual unsigned int offset671(int)
		{
			return offset = 671;
		}

		virtual unsigned int offset672(int)
		{
			return offset = 672;
		}

		virtual unsigned int offset673(int)
		{
			return offset = 673;
		}

		virtual unsigned int offset674(int)
		{
			return offset = 674;
		}

		virtual unsigned int offset675(int)
		{
			return offset = 675;
		}

		virtual unsigned int offset676(int)
		{
			return offset = 676;
		}

		virtual unsigned int offset677(int)
		{
			return offset = 677;
		}

		virtual unsigned int offset678(int)
		{
			return offset = 678;
		}

		virtual unsigned int offset679(int)
		{
			return offset = 679;
		}

		virtual unsigned int offset680(int)
		{
			return offset = 680;
		}

		virtual unsigned int offset681(int)
		{
			return offset = 681;
		}

		virtual unsigned int offset682(int)
		{
			return offset = 682;
		}

		virtual unsigned int offset683(int)
		{
			return offset = 683;
		}

		virtual unsigned int offset684(int)
		{
			return offset = 684;
		}

		virtual unsigned int offset685(int)
		{
			return offset = 685;
		}

		virtual unsigned int offset686(int)
		{
			return offset = 686;
		}

		virtual unsigned int offset687(int)
		{
			return offset = 687;
		}

		virtual unsigned int offset688(int)
		{
			return offset = 688;
		}

		virtual unsigned int offset689(int)
		{
			return offset = 689;
		}

		virtual unsigned int offset690(int)
		{
			return offset = 690;
		}

		virtual unsigned int offset691(int)
		{
			return offset = 691;
		}

		virtual unsigned int offset692(int)
		{
			return offset = 692;
		}

		virtual unsigned int offset693(int)
		{
			return offset = 693;
		}

		virtual unsigned int offset694(int)
		{
			return offset = 694;
		}

		virtual unsigned int offset695(int)
		{
			return offset = 695;
		}

		virtual unsigned int offset696(int)
		{
			return offset = 696;
		}

		virtual unsigned int offset697(int)
		{
			return offset = 697;
		}

		virtual unsigned int offset698(int)
		{
			return offset = 698;
		}

		virtual unsigned int offset699(int)
		{
			return offset = 699;
		}


		virtual unsigned int offset700(int)
		{
			return offset = 700;
		}

		virtual unsigned int offset701(int)
		{
			return offset = 701;
		}

		virtual unsigned int offset702(int)
		{
			return offset = 702;
		}

		virtual unsigned int offset703(int)
		{
			return offset = 703;
		}

		virtual unsigned int offset704(int)
		{
			return offset = 704;
		}

		virtual unsigned int offset705(int)
		{
			return offset = 705;
		}

		virtual unsigned int offset706(int)
		{
			return offset = 706;
		}

		virtual unsigned int offset707(int)
		{
			return offset = 707;
		}

		virtual unsigned int offset708(int)
		{
			return offset = 708;
		}

		virtual unsigned int offset709(int)
		{
			return offset = 709;
		}

		virtual unsigned int offset710(int)
		{
			return offset = 710;
		}

		virtual unsigned int offset711(int)
		{
			return offset = 711;
		}

		virtual unsigned int offset712(int)
		{
			return offset = 712;
		}

		virtual unsigned int offset713(int)
		{
			return offset = 713;
		}

		virtual unsigned int offset714(int)
		{
			return offset = 714;
		}

		virtual unsigned int offset715(int)
		{
			return offset = 715;
		}

		virtual unsigned int offset716(int)
		{
			return offset = 716;
		}

		virtual unsigned int offset717(int)
		{
			return offset = 717;
		}

		virtual unsigned int offset718(int)
		{
			return offset = 718;
		}

		virtual unsigned int offset719(int)
		{
			return offset = 719;
		}

		virtual unsigned int offset720(int)
		{
			return offset = 720;
		}

		virtual unsigned int offset721(int)
		{
			return offset = 721;
		}

		virtual unsigned int offset722(int)
		{
			return offset = 722;
		}

		virtual unsigned int offset723(int)
		{
			return offset = 723;
		}

		virtual unsigned int offset724(int)
		{
			return offset = 724;
		}

		virtual unsigned int offset725(int)
		{
			return offset = 725;
		}

		virtual unsigned int offset726(int)
		{
			return offset = 726;
		}

		virtual unsigned int offset727(int)
		{
			return offset = 727;
		}

		virtual unsigned int offset728(int)
		{
			return offset = 728;
		}

		virtual unsigned int offset729(int)
		{
			return offset = 729;
		}

		virtual unsigned int offset730(int)
		{
			return offset = 730;
		}

		virtual unsigned int offset731(int)
		{
			return offset = 731;
		}

		virtual unsigned int offset732(int)
		{
			return offset = 732;
		}

		virtual unsigned int offset733(int)
		{
			return offset = 733;
		}

		virtual unsigned int offset734(int)
		{
			return offset = 734;
		}

		virtual unsigned int offset735(int)
		{
			return offset = 735;
		}

		virtual unsigned int offset736(int)
		{
			return offset = 736;
		}

		virtual unsigned int offset737(int)
		{
			return offset = 737;
		}

		virtual unsigned int offset738(int)
		{
			return offset = 738;
		}

		virtual unsigned int offset739(int)
		{
			return offset = 739;
		}

		virtual unsigned int offset740(int)
		{
			return offset = 740;
		}

		virtual unsigned int offset741(int)
		{
			return offset = 741;
		}

		virtual unsigned int offset742(int)
		{
			return offset = 742;
		}

		virtual unsigned int offset743(int)
		{
			return offset = 743;
		}

		virtual unsigned int offset744(int)
		{
			return offset = 744;
		}

		virtual unsigned int offset745(int)
		{
			return offset = 745;
		}

		virtual unsigned int offset746(int)
		{
			return offset = 746;
		}

		virtual unsigned int offset747(int)
		{
			return offset = 747;
		}

		virtual unsigned int offset748(int)
		{
			return offset = 748;
		}

		virtual unsigned int offset749(int)
		{
			return offset = 749;
		}

		virtual unsigned int offset750(int)
		{
			return offset = 750;
		}

		virtual unsigned int offset751(int)
		{
			return offset = 751;
		}

		virtual unsigned int offset752(int)
		{
			return offset = 752;
		}

		virtual unsigned int offset753(int)
		{
			return offset = 753;
		}

		virtual unsigned int offset754(int)
		{
			return offset = 754;
		}

		virtual unsigned int offset755(int)
		{
			return offset = 755;
		}

		virtual unsigned int offset756(int)
		{
			return offset = 756;
		}

		virtual unsigned int offset757(int)
		{
			return offset = 757;
		}

		virtual unsigned int offset758(int)
		{
			return offset = 758;
		}

		virtual unsigned int offset759(int)
		{
			return offset = 759;
		}

		virtual unsigned int offset760(int)
		{
			return offset = 760;
		}

		virtual unsigned int offset761(int)
		{
			return offset = 761;
		}

		virtual unsigned int offset762(int)
		{
			return offset = 762;
		}

		virtual unsigned int offset763(int)
		{
			return offset = 763;
		}

		virtual unsigned int offset764(int)
		{
			return offset = 764;
		}

		virtual unsigned int offset765(int)
		{
			return offset = 765;
		}

		virtual unsigned int offset766(int)
		{
			return offset = 766;
		}

		virtual unsigned int offset767(int)
		{
			return offset = 767;
		}

		virtual unsigned int offset768(int)
		{
			return offset = 768;
		}

		virtual unsigned int offset769(int)
		{
			return offset = 769;
		}

		virtual unsigned int offset770(int)
		{
			return offset = 770;
		}

		virtual unsigned int offset771(int)
		{
			return offset = 771;
		}

		virtual unsigned int offset772(int)
		{
			return offset = 772;
		}

		virtual unsigned int offset773(int)
		{
			return offset = 773;
		}

		virtual unsigned int offset774(int)
		{
			return offset = 774;
		}

		virtual unsigned int offset775(int)
		{
			return offset = 775;
		}

		virtual unsigned int offset776(int)
		{
			return offset = 776;
		}

		virtual unsigned int offset777(int)
		{
			return offset = 777;
		}

		virtual unsigned int offset778(int)
		{
			return offset = 778;
		}

		virtual unsigned int offset779(int)
		{
			return offset = 779;
		}

		virtual unsigned int offset780(int)
		{
			return offset = 780;
		}

		virtual unsigned int offset781(int)
		{
			return offset = 781;
		}

		virtual unsigned int offset782(int)
		{
			return offset = 782;
		}

		virtual unsigned int offset783(int)
		{
			return offset = 783;
		}

		virtual unsigned int offset784(int)
		{
			return offset = 784;
		}

		virtual unsigned int offset785(int)
		{
			return offset = 785;
		}

		virtual unsigned int offset786(int)
		{
			return offset = 786;
		}

		virtual unsigned int offset787(int)
		{
			return offset = 787;
		}

		virtual unsigned int offset788(int)
		{
			return offset = 788;
		}

		virtual unsigned int offset789(int)
		{
			return offset = 789;
		}

		virtual unsigned int offset790(int)
		{
			return offset = 790;
		}

		virtual unsigned int offset791(int)
		{
			return offset = 791;
		}

		virtual unsigned int offset792(int)
		{
			return offset = 792;
		}

		virtual unsigned int offset793(int)
		{
			return offset = 793;
		}

		virtual unsigned int offset794(int)
		{
			return offset = 794;
		}

		virtual unsigned int offset795(int)
		{
			return offset = 795;
		}

		virtual unsigned int offset796(int)
		{
			return offset = 796;
		}

		virtual unsigned int offset797(int)
		{
			return offset = 797;
		}

		virtual unsigned int offset798(int)
		{
			return offset = 798;
		}

		virtual unsigned int offset799(int)
		{
			return offset = 799;
		}


		virtual unsigned int offset800(int)
		{
			return offset = 800;
		}

		virtual unsigned int offset801(int)
		{
			return offset = 801;
		}

		virtual unsigned int offset802(int)
		{
			return offset = 802;
		}

		virtual unsigned int offset803(int)
		{
			return offset = 803;
		}

		virtual unsigned int offset804(int)
		{
			return offset = 804;
		}

		virtual unsigned int offset805(int)
		{
			return offset = 805;
		}

		virtual unsigned int offset806(int)
		{
			return offset = 806;
		}

		virtual unsigned int offset807(int)
		{
			return offset = 807;
		}

		virtual unsigned int offset808(int)
		{
			return offset = 808;
		}

		virtual unsigned int offset809(int)
		{
			return offset = 809;
		}

		virtual unsigned int offset810(int)
		{
			return offset = 810;
		}

		virtual unsigned int offset811(int)
		{
			return offset = 811;
		}

		virtual unsigned int offset812(int)
		{
			return offset = 812;
		}

		virtual unsigned int offset813(int)
		{
			return offset = 813;
		}

		virtual unsigned int offset814(int)
		{
			return offset = 814;
		}

		virtual unsigned int offset815(int)
		{
			return offset = 815;
		}

		virtual unsigned int offset816(int)
		{
			return offset = 816;
		}

		virtual unsigned int offset817(int)
		{
			return offset = 817;
		}

		virtual unsigned int offset818(int)
		{
			return offset = 818;
		}

		virtual unsigned int offset819(int)
		{
			return offset = 819;
		}

		virtual unsigned int offset820(int)
		{
			return offset = 820;
		}

		virtual unsigned int offset821(int)
		{
			return offset = 821;
		}

		virtual unsigned int offset822(int)
		{
			return offset = 822;
		}

		virtual unsigned int offset823(int)
		{
			return offset = 823;
		}

		virtual unsigned int offset824(int)
		{
			return offset = 824;
		}

		virtual unsigned int offset825(int)
		{
			return offset = 825;
		}

		virtual unsigned int offset826(int)
		{
			return offset = 826;
		}

		virtual unsigned int offset827(int)
		{
			return offset = 827;
		}

		virtual unsigned int offset828(int)
		{
			return offset = 828;
		}

		virtual unsigned int offset829(int)
		{
			return offset = 829;
		}

		virtual unsigned int offset830(int)
		{
			return offset = 830;
		}

		virtual unsigned int offset831(int)
		{
			return offset = 831;
		}

		virtual unsigned int offset832(int)
		{
			return offset = 832;
		}

		virtual unsigned int offset833(int)
		{
			return offset = 833;
		}

		virtual unsigned int offset834(int)
		{
			return offset = 834;
		}

		virtual unsigned int offset835(int)
		{
			return offset = 835;
		}

		virtual unsigned int offset836(int)
		{
			return offset = 836;
		}

		virtual unsigned int offset837(int)
		{
			return offset = 837;
		}

		virtual unsigned int offset838(int)
		{
			return offset = 838;
		}

		virtual unsigned int offset839(int)
		{
			return offset = 839;
		}

		virtual unsigned int offset840(int)
		{
			return offset = 840;
		}

		virtual unsigned int offset841(int)
		{
			return offset = 841;
		}

		virtual unsigned int offset842(int)
		{
			return offset = 842;
		}

		virtual unsigned int offset843(int)
		{
			return offset = 843;
		}

		virtual unsigned int offset844(int)
		{
			return offset = 844;
		}

		virtual unsigned int offset845(int)
		{
			return offset = 845;
		}

		virtual unsigned int offset846(int)
		{
			return offset = 846;
		}

		virtual unsigned int offset847(int)
		{
			return offset = 847;
		}

		virtual unsigned int offset848(int)
		{
			return offset = 848;
		}

		virtual unsigned int offset849(int)
		{
			return offset = 849;
		}

		virtual unsigned int offset850(int)
		{
			return offset = 850;
		}

		virtual unsigned int offset851(int)
		{
			return offset = 851;
		}

		virtual unsigned int offset852(int)
		{
			return offset = 852;
		}

		virtual unsigned int offset853(int)
		{
			return offset = 853;
		}

		virtual unsigned int offset854(int)
		{
			return offset = 854;
		}

		virtual unsigned int offset855(int)
		{
			return offset = 855;
		}

		virtual unsigned int offset856(int)
		{
			return offset = 856;
		}

		virtual unsigned int offset857(int)
		{
			return offset = 857;
		}

		virtual unsigned int offset858(int)
		{
			return offset = 858;
		}

		virtual unsigned int offset859(int)
		{
			return offset = 859;
		}

		virtual unsigned int offset860(int)
		{
			return offset = 860;
		}

		virtual unsigned int offset861(int)
		{
			return offset = 861;
		}

		virtual unsigned int offset862(int)
		{
			return offset = 862;
		}

		virtual unsigned int offset863(int)
		{
			return offset = 863;
		}

		virtual unsigned int offset864(int)
		{
			return offset = 864;
		}

		virtual unsigned int offset865(int)
		{
			return offset = 865;
		}

		virtual unsigned int offset866(int)
		{
			return offset = 866;
		}

		virtual unsigned int offset867(int)
		{
			return offset = 867;
		}

		virtual unsigned int offset868(int)
		{
			return offset = 868;
		}

		virtual unsigned int offset869(int)
		{
			return offset = 869;
		}

		virtual unsigned int offset870(int)
		{
			return offset = 870;
		}

		virtual unsigned int offset871(int)
		{
			return offset = 871;
		}

		virtual unsigned int offset872(int)
		{
			return offset = 872;
		}

		virtual unsigned int offset873(int)
		{
			return offset = 873;
		}

		virtual unsigned int offset874(int)
		{
			return offset = 874;
		}

		virtual unsigned int offset875(int)
		{
			return offset = 875;
		}

		virtual unsigned int offset876(int)
		{
			return offset = 876;
		}

		virtual unsigned int offset877(int)
		{
			return offset = 877;
		}

		virtual unsigned int offset878(int)
		{
			return offset = 878;
		}

		virtual unsigned int offset879(int)
		{
			return offset = 879;
		}

		virtual unsigned int offset880(int)
		{
			return offset = 880;
		}

		virtual unsigned int offset881(int)
		{
			return offset = 881;
		}

		virtual unsigned int offset882(int)
		{
			return offset = 882;
		}

		virtual unsigned int offset883(int)
		{
			return offset = 883;
		}

		virtual unsigned int offset884(int)
		{
			return offset = 884;
		}

		virtual unsigned int offset885(int)
		{
			return offset = 885;
		}

		virtual unsigned int offset886(int)
		{
			return offset = 886;
		}

		virtual unsigned int offset887(int)
		{
			return offset = 887;
		}

		virtual unsigned int offset888(int)
		{
			return offset = 888;
		}

		virtual unsigned int offset889(int)
		{
			return offset = 889;
		}

		virtual unsigned int offset890(int)
		{
			return offset = 890;
		}

		virtual unsigned int offset891(int)
		{
			return offset = 891;
		}

		virtual unsigned int offset892(int)
		{
			return offset = 892;
		}

		virtual unsigned int offset893(int)
		{
			return offset = 893;
		}

		virtual unsigned int offset894(int)
		{
			return offset = 894;
		}

		virtual unsigned int offset895(int)
		{
			return offset = 895;
		}

		virtual unsigned int offset896(int)
		{
			return offset = 896;
		}

		virtual unsigned int offset897(int)
		{
			return offset = 897;
		}

		virtual unsigned int offset898(int)
		{
			return offset = 898;
		}

		virtual unsigned int offset899(int)
		{
			return offset = 899;
		}


		virtual unsigned int offset900(int)
		{
			return offset = 900;
		}

		virtual unsigned int offset901(int)
		{
			return offset = 901;
		}

		virtual unsigned int offset902(int)
		{
			return offset = 902;
		}

		virtual unsigned int offset903(int)
		{
			return offset = 903;
		}

		virtual unsigned int offset904(int)
		{
			return offset = 904;
		}

		virtual unsigned int offset905(int)
		{
			return offset = 905;
		}

		virtual unsigned int offset906(int)
		{
			return offset = 906;
		}

		virtual unsigned int offset907(int)
		{
			return offset = 907;
		}

		virtual unsigned int offset908(int)
		{
			return offset = 908;
		}

		virtual unsigned int offset909(int)
		{
			return offset = 909;
		}

		virtual unsigned int offset910(int)
		{
			return offset = 910;
		}

		virtual unsigned int offset911(int)
		{
			return offset = 911;
		}

		virtual unsigned int offset912(int)
		{
			return offset = 912;
		}

		virtual unsigned int offset913(int)
		{
			return offset = 913;
		}

		virtual unsigned int offset914(int)
		{
			return offset = 914;
		}

		virtual unsigned int offset915(int)
		{
			return offset = 915;
		}

		virtual unsigned int offset916(int)
		{
			return offset = 916;
		}

		virtual unsigned int offset917(int)
		{
			return offset = 917;
		}

		virtual unsigned int offset918(int)
		{
			return offset = 918;
		}

		virtual unsigned int offset919(int)
		{
			return offset = 919;
		}

		virtual unsigned int offset920(int)
		{
			return offset = 920;
		}

		virtual unsigned int offset921(int)
		{
			return offset = 921;
		}

		virtual unsigned int offset922(int)
		{
			return offset = 922;
		}

		virtual unsigned int offset923(int)
		{
			return offset = 923;
		}

		virtual unsigned int offset924(int)
		{
			return offset = 924;
		}

		virtual unsigned int offset925(int)
		{
			return offset = 925;
		}

		virtual unsigned int offset926(int)
		{
			return offset = 926;
		}

		virtual unsigned int offset927(int)
		{
			return offset = 927;
		}

		virtual unsigned int offset928(int)
		{
			return offset = 928;
		}

		virtual unsigned int offset929(int)
		{
			return offset = 929;
		}

		virtual unsigned int offset930(int)
		{
			return offset = 930;
		}

		virtual unsigned int offset931(int)
		{
			return offset = 931;
		}

		virtual unsigned int offset932(int)
		{
			return offset = 932;
		}

		virtual unsigned int offset933(int)
		{
			return offset = 933;
		}

		virtual unsigned int offset934(int)
		{
			return offset = 934;
		}

		virtual unsigned int offset935(int)
		{
			return offset = 935;
		}

		virtual unsigned int offset936(int)
		{
			return offset = 936;
		}

		virtual unsigned int offset937(int)
		{
			return offset = 937;
		}

		virtual unsigned int offset938(int)
		{
			return offset = 938;
		}

		virtual unsigned int offset939(int)
		{
			return offset = 939;
		}

		virtual unsigned int offset940(int)
		{
			return offset = 940;
		}

		virtual unsigned int offset941(int)
		{
			return offset = 941;
		}

		virtual unsigned int offset942(int)
		{
			return offset = 942;
		}

		virtual unsigned int offset943(int)
		{
			return offset = 943;
		}

		virtual unsigned int offset944(int)
		{
			return offset = 944;
		}

		virtual unsigned int offset945(int)
		{
			return offset = 945;
		}

		virtual unsigned int offset946(int)
		{
			return offset = 946;
		}

		virtual unsigned int offset947(int)
		{
			return offset = 947;
		}

		virtual unsigned int offset948(int)
		{
			return offset = 948;
		}

		virtual unsigned int offset949(int)
		{
			return offset = 949;
		}

		virtual unsigned int offset950(int)
		{
			return offset = 950;
		}

		virtual unsigned int offset951(int)
		{
			return offset = 951;
		}

		virtual unsigned int offset952(int)
		{
			return offset = 952;
		}

		virtual unsigned int offset953(int)
		{
			return offset = 953;
		}

		virtual unsigned int offset954(int)
		{
			return offset = 954;
		}

		virtual unsigned int offset955(int)
		{
			return offset = 955;
		}

		virtual unsigned int offset956(int)
		{
			return offset = 956;
		}

		virtual unsigned int offset957(int)
		{
			return offset = 957;
		}

		virtual unsigned int offset958(int)
		{
			return offset = 958;
		}

		virtual unsigned int offset959(int)
		{
			return offset = 959;
		}

		virtual unsigned int offset960(int)
		{
			return offset = 960;
		}

		virtual unsigned int offset961(int)
		{
			return offset = 961;
		}

		virtual unsigned int offset962(int)
		{
			return offset = 962;
		}

		virtual unsigned int offset963(int)
		{
			return offset = 963;
		}

		virtual unsigned int offset964(int)
		{
			return offset = 964;
		}

		virtual unsigned int offset965(int)
		{
			return offset = 965;
		}

		virtual unsigned int offset966(int)
		{
			return offset = 966;
		}

		virtual unsigned int offset967(int)
		{
			return offset = 967;
		}

		virtual unsigned int offset968(int)
		{
			return offset = 968;
		}

		virtual unsigned int offset969(int)
		{
			return offset = 969;
		}

		virtual unsigned int offset970(int)
		{
			return offset = 970;
		}

		virtual unsigned int offset971(int)
		{
			return offset = 971;
		}

		virtual unsigned int offset972(int)
		{
			return offset = 972;
		}

		virtual unsigned int offset973(int)
		{
			return offset = 973;
		}

		virtual unsigned int offset974(int)
		{
			return offset = 974;
		}

		virtual unsigned int offset975(int)
		{
			return offset = 975;
		}

		virtual unsigned int offset976(int)
		{
			return offset = 976;
		}

		virtual unsigned int offset977(int)
		{
			return offset = 977;
		}

		virtual unsigned int offset978(int)
		{
			return offset = 978;
		}

		virtual unsigned int offset979(int)
		{
			return offset = 979;
		}

		virtual unsigned int offset980(int)
		{
			return offset = 980;
		}

		virtual unsigned int offset981(int)
		{
			return offset = 981;
		}

		virtual unsigned int offset982(int)
		{
			return offset = 982;
		}

		virtual unsigned int offset983(int)
		{
			return offset = 983;
		}

		virtual unsigned int offset984(int)
		{
			return offset = 984;
		}

		virtual unsigned int offset985(int)
		{
			return offset = 985;
		}

		virtual unsigned int offset986(int)
		{
			return offset = 986;
		}

		virtual unsigned int offset987(int)
		{
			return offset = 987;
		}

		virtual unsigned int offset988(int)
		{
			return offset = 988;
		}

		virtual unsigned int offset989(int)
		{
			return offset = 989;
		}

		virtual unsigned int offset990(int)
		{
			return offset = 990;
		}

		virtual unsigned int offset991(int)
		{
			return offset = 991;
		}

		virtual unsigned int offset992(int)
		{
			return offset = 992;
		}

		virtual unsigned int offset993(int)
		{
			return offset = 993;
		}

		virtual unsigned int offset994(int)
		{
			return offset = 994;
		}

		virtual unsigned int offset995(int)
		{
			return offset = 995;
		}

		virtual unsigned int offset996(int)
		{
			return offset = 996;
		}

		virtual unsigned int offset997(int)
		{
			return offset = 997;
		}

		virtual unsigned int offset998(int)
		{
			return offset = 998;
		}

		virtual unsigned int offset999(int)
		{
			return offset = 999;
		}

		virtual unsigned int offset1000(int)
		{
			return offset = 1000;
		}

	};
}
namespace fakeit
{

	template<typename TARGET, typename SOURCE>
	TARGET union_cast(SOURCE source)
	{

		union
		{
			SOURCE source;
			TARGET target;
		} u;
		u.source = source;
		return u.target;
	}

}

namespace fakeit
{
	class NoVirtualDtor : public std::runtime_error
	{
	public:
		NoVirtualDtor() : std::runtime_error("Can't mock the destructor. No virtual destructor was found")
		{
		}
	};

	class VTUtils
	{
	public:

		template<typename C, typename R, typename ... arglist>
		static unsigned int getOffset(R (C::*vMethod)(arglist...))
		{
			auto sMethod = reinterpret_cast<unsigned int (VirtualOffsetSelector::*)(int)>(vMethod);
			VirtualOffsetSelector offsetSelctor;
			return (offsetSelctor.*sMethod)(0);
		}

		template<typename C>
		static typename std::enable_if<std::has_virtual_destructor<C>::value, unsigned int>::type
		getDestructorOffset()
		{
			VirtualOffsetSelector offsetSelctor;
			union_cast<C*>(&offsetSelctor)->~C();
			return offsetSelctor.offset;
		}

		template<typename C>
		static typename std::enable_if<!std::has_virtual_destructor<C>::value, unsigned int>::type
		getDestructorOffset()
		{
			throw NoVirtualDtor();
		}

		template<typename C>
		static typename std::enable_if<std::has_virtual_destructor<C>::value, bool>::type
		hasVirtualDestructor()
		{
			return true;
		}

		template<typename C>
		static typename std::enable_if<!std::has_virtual_destructor<C>::value, bool>::type
		hasVirtualDestructor()
		{
			return false;
		}

		template<typename C>
		static unsigned int getVTSize()
		{
			struct Derrived : public C
			{
				virtual void endOfVt()
				{
				}
			};

			unsigned int vtSize = getOffset(&Derrived::endOfVt);
			return vtSize;
		}
	};


}
#ifdef _MSC_VER
																														namespace fakeit {

    typedef unsigned long dword_;

    struct TypeDescriptor {
        TypeDescriptor() :
                ptrToVTable(0), spare(0) {

            int **tiVFTPtr = (int **) (&typeid(void));
            int *i = (int *) tiVFTPtr[0];
			char *type_info_vft_ptr = (char *) i;
            ptrToVTable = type_info_vft_ptr;
        }

		char *ptrToVTable;
        dword_ spare;
        char name[8];
    };

    struct PMD {



        int mdisp;

        int pdisp;
        int vdisp;

        PMD() :
                mdisp(0), pdisp(-1), vdisp(0) {
        }
    };

    struct RTTIBaseClassDescriptor {
        RTTIBaseClassDescriptor() :
                pTypeDescriptor(nullptr), numContainedBases(0), attributes(0) {
        }

        const std::type_info *pTypeDescriptor;
        dword_ numContainedBases;
        struct PMD where;
        dword_ attributes;
    };

    template<typename C, typename... baseclasses>
    struct RTTIClassHierarchyDescriptor {
        RTTIClassHierarchyDescriptor() :
                signature(0),
                attributes(0),
                numBaseClasses(0),
                pBaseClassArray(nullptr) {
            pBaseClassArray = new RTTIBaseClassDescriptor *[1 + sizeof...(baseclasses)];
            addBaseClass < C, baseclasses...>();
        }

        ~RTTIClassHierarchyDescriptor() {
            for (int i = 0; i < 1 + sizeof...(baseclasses); i++) {
                RTTIBaseClassDescriptor *desc = pBaseClassArray[i];
                delete desc;
            }
            delete[] pBaseClassArray;
        }

        dword_ signature;
        dword_ attributes;
        dword_ numBaseClasses;
        RTTIBaseClassDescriptor **pBaseClassArray;

        template<typename BaseType>
        void addBaseClass() {
            static_assert(std::is_base_of<BaseType, C>::value, "C must be a derived class of BaseType");
            RTTIBaseClassDescriptor *desc = new RTTIBaseClassDescriptor();
            desc->pTypeDescriptor = &typeid(BaseType);
            pBaseClassArray[numBaseClasses] = desc;
            for (unsigned int i = 0; i < numBaseClasses; i++) {
                pBaseClassArray[i]->numContainedBases++;
            }
            numBaseClasses++;
        }

        template<typename head, typename B1, typename... tail>
        void addBaseClass() {
            static_assert(std::is_base_of<B1, head>::value, "invalid inheritance list");
            addBaseClass<head>();
            addBaseClass<B1, tail...>();
        }

    };

	template<typename C, typename... baseclasses>
	struct RTTICompleteObjectLocator {
#ifdef _WIN64
		RTTICompleteObjectLocator(const std::type_info &unused) :
			signature(0), offset(0), cdOffset(0),
			typeDescriptorOffset(0), classDescriptorOffset(0)
		{
                    (void)unused;
		}

		dword_ signature;
		dword_ offset;
		dword_ cdOffset;
		dword_ typeDescriptorOffset;
		dword_ classDescriptorOffset;
#else
		RTTICompleteObjectLocator(const std::type_info &info) :
			signature(0), offset(0), cdOffset(0),
			pTypeDescriptor(&info),
			pClassDescriptor(new RTTIClassHierarchyDescriptor<C, baseclasses...>()) {
		}

		~RTTICompleteObjectLocator() {
			delete pClassDescriptor;
		}

		dword_ signature;
		dword_ offset;
		dword_ cdOffset;
		const std::type_info *pTypeDescriptor;
		struct RTTIClassHierarchyDescriptor<C, baseclasses...> *pClassDescriptor;
#endif
	};


    struct VirtualTableBase {

        static VirtualTableBase &getVTable(void *instance) {
            fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance);
            return *vt;
        }

        VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { }

        void *getCookie(int index) {
            return _firstMethod[-2 - index];
        }

        void setCookie(int index, void *value) {
            _firstMethod[-2 - index] = value;
        }

        void *getMethod(unsigned int index) const {
            return _firstMethod[index];
        }

        void setMethod(unsigned int index, void *method) {
            _firstMethod[index] = method;
        }

    protected:
        void **_firstMethod;
    };

    template<class C, class... baseclasses>
    struct VirtualTable : public VirtualTableBase {

        class Handle {

            friend struct VirtualTable<C, baseclasses...>;

            void **firstMethod;

            Handle(void **method) : firstMethod(method) { }

        public:

            VirtualTable<C, baseclasses...> &restore() {
                VirtualTable<C, baseclasses...> *vt = (VirtualTable<C, baseclasses...> *) this;
                return *vt;
            }
        };

        static VirtualTable<C, baseclasses...> &getVTable(C &instance) {
            fakeit::VirtualTable<C, baseclasses...> *vt = (fakeit::VirtualTable<C, baseclasses...> *) (&instance);
            return *vt;
        }

        void copyFrom(VirtualTable<C, baseclasses...> &from) {
            unsigned int size = VTUtils::getVTSize<C>();
            for (unsigned int i = 0; i < size; i++) {
                _firstMethod[i] = from.getMethod(i);
            }
        }

        VirtualTable() : VirtualTable(buildVTArray()) {
        }

        ~VirtualTable() {

        }

        void dispose() {
            _firstMethod--;
            RTTICompleteObjectLocator<C, baseclasses...> *locator = (RTTICompleteObjectLocator<C, baseclasses...> *) _firstMethod[0];
            delete locator;
            _firstMethod -= numOfCookies;
            delete[] _firstMethod;
        }


        unsigned int dtor(int) {
            C *c = (C *) this;
            C &cRef = *c;
            auto vt = VirtualTable<C, baseclasses...>::getVTable(cRef);
            void *dtorPtr = vt.getCookie(numOfCookies - 1);
            void(*method)(C *) = reinterpret_cast<void (*)(C *)>(dtorPtr);
            method(c);
            return 0;
        }

        void setDtor(void *method) {





            void *dtorPtr = union_cast<void *>(&VirtualTable<C, baseclasses...>::dtor);
            unsigned int index = VTUtils::getDestructorOffset<C>();
            _firstMethod[index] = dtorPtr;
            setCookie(numOfCookies - 1, method);
        }

        unsigned int getSize() {
            return VTUtils::getVTSize<C>();
        }

        void initAll(void *value) {
            auto size = getSize();
            for (unsigned int i = 0; i < size; i++) {
                setMethod(i, value);
            }
        }

        Handle createHandle() {
            Handle h(_firstMethod);
            return h;
        }

    private:

        class SimpleType {
        };

        static_assert(sizeof(unsigned int (SimpleType::*)()) == sizeof(unsigned int (C::*)()),
            "Can't mock a type with multiple inheritance or with non-polymorphic base class");
        static const unsigned int numOfCookies = 3;

        static void **buildVTArray() {
            int vtSize = VTUtils::getVTSize<C>();
            auto array = new void *[vtSize + numOfCookies + 1]{};
            RTTICompleteObjectLocator<C, baseclasses...> *objectLocator = new RTTICompleteObjectLocator<C, baseclasses...>(
                    typeid(C));
            array += numOfCookies;
            array[0] = objectLocator;
            array++;
            return array;
        }

        VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) {
        }
    };
}
#else
#ifndef __clang__
																														#include <type_traits>
#include <tr2/type_traits>

namespace fakeit {
    template<typename ... T1>
    class has_one_base {
    };

    template<typename T1, typename T2, typename ... types>
    class has_one_base<std::tr2::__reflection_typelist<T1, T2, types...>> : public std::false_type {
    };

    template<typename T1>
    class has_one_base<std::tr2::__reflection_typelist<T1>>
            : public has_one_base<typename std::tr2::direct_bases<T1>::type> {
    };

    template<>
    class has_one_base<std::tr2::__reflection_typelist<>> : public std::true_type {
    };

    template<typename T>
    class is_simple_inheritance_layout : public has_one_base<typename std::tr2::direct_bases<T>::type> {
    };
}

#endif

namespace fakeit
{

	struct VirtualTableBase
	{

		static VirtualTableBase& getVTable(void* instance)
		{
			fakeit::VirtualTableBase* vt = (fakeit::VirtualTableBase*)(instance);
			return *vt;
		}

		VirtualTableBase(void** firstMethod) : _firstMethod(firstMethod)
		{
		}

		void* getCookie(int index)
		{
			return _firstMethod[-3 - index];
		}

		void setCookie(int index, void* value)
		{
			_firstMethod[-3 - index] = value;
		}

		void* getMethod(unsigned int index) const
		{
			return _firstMethod[index];
		}

		void setMethod(unsigned int index, void* method)
		{
			_firstMethod[index] = method;
		}

	protected:
		void** _firstMethod;
	};

	template<class C, class ... baseclasses>
	struct VirtualTable : public VirtualTableBase
	{

#ifndef __clang__
		static_assert(is_simple_inheritance_layout<C>::value, "Can't mock a type with multiple inheritance");
#endif

		class Handle
		{

			friend struct VirtualTable<C, baseclasses...>;
			void** firstMethod;

			Handle(void** method) :
					firstMethod(method)
			{
			}

		public:

			VirtualTable<C, baseclasses...>& restore()
			{
				VirtualTable<C, baseclasses...>* vt = (VirtualTable<C, baseclasses...>*)this;
				return *vt;
			}
		};

		static VirtualTable<C, baseclasses...>& getVTable(C& instance)
		{
			fakeit::VirtualTable<C, baseclasses...>* vt = (fakeit::VirtualTable<C, baseclasses...>*)(&instance);
			return *vt;
		}

		void copyFrom(VirtualTable<C, baseclasses...>& from)
		{
			unsigned int size = VTUtils::getVTSize<C>();

			for (size_t i = 0; i < size; ++i)
			{
				_firstMethod[i] = from.getMethod(i);
			}
		}

		VirtualTable() :
				VirtualTable(buildVTArray())
		{
		}

		void dispose()
		{
			_firstMethod--;
			_firstMethod--;
			_firstMethod -= numOfCookies;
			delete[] _firstMethod;
		}

		unsigned int dtor(int)
		{
			C* c = (C*)this;
			C& cRef = *c;
			auto vt = VirtualTable<C, baseclasses...>::getVTable(cRef);
			unsigned int index = VTUtils::getDestructorOffset<C>();
			void* dtorPtr = vt.getMethod(index);
			void (* method)(C*) = union_cast<void (*)(C*)>(dtorPtr);
			method(c);
			return 0;
		}


		void setDtor(void* method)
		{
			unsigned int index = VTUtils::getDestructorOffset<C>();
			void* dtorPtr = union_cast<void*>(&VirtualTable<C, baseclasses...>::dtor);


			_firstMethod[index] = method;

			_firstMethod[index + 1] = dtorPtr;
		}


		unsigned int getSize()
		{
			return VTUtils::getVTSize<C>();
		}

		void initAll(void* value)
		{
			unsigned int size = getSize();
			for (unsigned int i = 0; i < size; i++)
			{
				setMethod(i, value);
			}
		}

		const std::type_info* getTypeId()
		{
			return (const std::type_info*)(_firstMethod[-1]);
		}

		Handle createHandle()
		{
			Handle h(_firstMethod);
			return h;
		}

	private:
		static const unsigned int numOfCookies = 2;

		static void** buildVTArray()
		{
			int size = VTUtils::getVTSize<C>();
			auto array = new void* [size + 2 + numOfCookies]{};
			array += numOfCookies;
			array++;
			array[0] = const_cast<std::type_info*>(&typeid(C));
			array++;
			return array;
		}

		VirtualTable(void** firstMethod) : VirtualTableBase(firstMethod)
		{
		}

	};
}
#endif
namespace fakeit
{

	struct NoMoreRecordedActionException
	{
	};

	template<typename R, typename ... arglist>
	struct MethodInvocationHandler : Destructible
	{
		virtual R handleMethodInvocation(const typename fakeit::production_arg<arglist>::type... args) = 0;
	};

}

#include <new>

namespace fakeit
{

#ifdef __GNUG__
#ifndef __clang__
																															#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#endif


#ifdef _MSC_VER
																															#pragma warning( push )
#pragma warning( disable : 4200 )
#endif


	template<typename C, typename ... baseclasses>
	class FakeObject
	{

		VirtualTable<C, baseclasses...> vtable;

		static const size_t SIZE = sizeof(C) - sizeof(VirtualTable<C, baseclasses...>);
		char instanceArea[SIZE ? SIZE : 0];

		FakeObject(FakeObject const&) = delete;

		FakeObject& operator=(FakeObject const&) = delete;

	public:

		FakeObject() : vtable()
		{
			initializeDataMembersArea();
		}

		~FakeObject()
		{
			vtable.dispose();
		}

		void initializeDataMembersArea()
		{
			for (size_t i = 0; i < SIZE; ++i) instanceArea[i] = (char)0;
		}

		void setMethod(unsigned int index, void* method)
		{
			vtable.setMethod(index, method);
		}

		VirtualTable<C, baseclasses...>& getVirtualTable()
		{
			return vtable;
		}

		void setVirtualTable(VirtualTable<C, baseclasses...>& t)
		{
			vtable = t;
		}

		void setDtor(void* dtor)
		{
			vtable.setDtor(dtor);
		}
	};

#ifdef _MSC_VER
#pragma warning( pop )
#endif

#ifdef __GNUG__
#ifndef __clang__
#pragma GCC diagnostic pop
#endif
#endif

}
namespace fakeit
{

	struct MethodProxy
	{

		MethodProxy(unsigned int id, unsigned int offset, void* vMethod) :
				_id(id),
				_offset(offset),
				_vMethod(vMethod)
		{
		}

		unsigned int getOffset() const
		{
			return _offset;
		}

		unsigned int getId() const
		{
			return _id;
		}

		void* getProxy() const
		{
			return union_cast<void*>(_vMethod);
		}

	private:
		unsigned int _id;
		unsigned int _offset;
		void* _vMethod;
	};
}

#include <utility>


namespace fakeit
{

	struct InvocationHandlerCollection
	{
		static const unsigned int VT_COOKIE_INDEX = 0;

		virtual Destructible* getInvocatoinHandlerPtrById(unsigned int index) = 0;

		static InvocationHandlerCollection* getInvocationHandlerCollection(void* instance)
		{
			VirtualTableBase& vt = VirtualTableBase::getVTable(instance);
			InvocationHandlerCollection* invocationHandlerCollection = (InvocationHandlerCollection*)vt.getCookie(
					InvocationHandlerCollection::VT_COOKIE_INDEX);
			return invocationHandlerCollection;
		}
	};


	template<typename R, typename ... arglist>
	class MethodProxyCreator
	{


	public:

		template<unsigned int id>
		MethodProxy createMethodProxy(unsigned int offset)
		{
			return MethodProxy(id, offset, union_cast<void*>(&MethodProxyCreator::methodProxyX<id>));
		}

	protected:

		R methodProxy(unsigned int id, const typename fakeit::production_arg<arglist>::type... args)
		{
			InvocationHandlerCollection* invocationHandlerCollection = InvocationHandlerCollection::getInvocationHandlerCollection(
					this);
			MethodInvocationHandler<R, arglist...>* invocationHandler =
					(MethodInvocationHandler<R, arglist...>*)invocationHandlerCollection->getInvocatoinHandlerPtrById(
							id);
			return invocationHandler->handleMethodInvocation(
					std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);
		}

		template<int id>
		R methodProxyX(arglist ... args)
		{
			return methodProxy(id, std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);
		}
	};
}

namespace fakeit
{

	class InvocationHandlers : public InvocationHandlerCollection
	{
		std::vector<std::shared_ptr<Destructible>>& _methodMocks;
		std::vector<unsigned int>& _offsets;

		unsigned int getOffset(unsigned int id) const
		{
			unsigned int offset = 0;
			for (; offset < _offsets.size(); offset++)
			{
				if (_offsets[offset] == id)
				{
					break;
				}
			}
			return offset;
		}

	public:
		InvocationHandlers(
				std::vector<std::shared_ptr<Destructible>>& methodMocks,
				std::vector<unsigned int>& offsets) :
				_methodMocks(methodMocks), _offsets(offsets)
		{
			for (std::vector<unsigned int>::iterator it = _offsets.begin(); it != _offsets.end(); ++it)
			{
				*it = std::numeric_limits<int>::max();
			}
		}

		Destructible* getInvocatoinHandlerPtrById(unsigned int id) override
		{
			unsigned int offset = getOffset(id);
			std::shared_ptr<Destructible> ptr = _methodMocks[offset];
			return ptr.get();
		}

	};

	template<typename C, typename ... baseclasses>
	struct DynamicProxy
	{

		static_assert(std::is_polymorphic<C>::value, "DynamicProxy requires a polymorphic type");

		DynamicProxy(C& inst) :
				instance(inst),
				originalVtHandle(VirtualTable<C, baseclasses...>::getVTable(instance).createHandle()),
				_methodMocks(VTUtils::getVTSize<C>()),
				_offsets(VTUtils::getVTSize<C>()),
				_invocationHandlers(_methodMocks, _offsets)
		{
			_cloneVt.copyFrom(originalVtHandle.restore());
			_cloneVt.setCookie(InvocationHandlerCollection::VT_COOKIE_INDEX, &_invocationHandlers);
			getFake().setVirtualTable(_cloneVt);
		}

		void detach()
		{
			getFake().setVirtualTable(originalVtHandle.restore());
		}

		~DynamicProxy()
		{
			_cloneVt.dispose();
		}

		C& get()
		{
			return instance;
		}

		void Reset()
		{
			_methodMocks = {};
			_methodMocks.resize(VTUtils::getVTSize<C>());
			_members = {};
			_offsets = {};
			_offsets.resize(VTUtils::getVTSize<C>());
			_cloneVt.copyFrom(originalVtHandle.restore());
		}

		void Clear()
		{
		}

		template<int id, typename R, typename ... arglist>
		void stubMethod(R(C::*vMethod)(arglist...), MethodInvocationHandler<R, arglist...>* methodInvocationHandler)
		{
			auto offset = VTUtils::getOffset(vMethod);
			MethodProxyCreator<R, arglist...> creator;
			bind(creator.template createMethodProxy<id + 1>(offset), methodInvocationHandler);
		}

		void stubDtor(MethodInvocationHandler<void>* methodInvocationHandler)
		{
			auto offset = VTUtils::getDestructorOffset<C>();
			MethodProxyCreator<void> creator;
			bindDtor(creator.createMethodProxy<0>(offset), methodInvocationHandler);
		}

		template<typename R, typename ... arglist>
		bool isMethodStubbed(R(C::*vMethod)(arglist...))
		{
			unsigned int offset = VTUtils::getOffset(vMethod);
			return isBinded(offset);
		}

		bool isDtorStubbed()
		{
			unsigned int offset = VTUtils::getDestructorOffset<C>();
			return isBinded(offset);
		}

		template<typename R, typename ... arglist>
		Destructible* getMethodMock(R(C::*vMethod)(arglist...))
		{
			auto offset = VTUtils::getOffset(vMethod);
			std::shared_ptr<Destructible> ptr = _methodMocks[offset];
			return ptr.get();
		}

		Destructible* getDtorMock()
		{
			auto offset = VTUtils::getDestructorOffset<C>();
			std::shared_ptr<Destructible> ptr = _methodMocks[offset];
			return ptr.get();
		}

		template<typename DATA_TYPE, typename ... arglist>
		void stubDataMember(DATA_TYPE C::*member, const arglist& ... initargs)
		{
			DATA_TYPE C::*theMember = (DATA_TYPE C::*)member;
			C& mock = get();
			DATA_TYPE* memberPtr = &(mock.*theMember);
			_members.push_back(
					std::shared_ptr<DataMemeberWrapper < DATA_TYPE, arglist...> >
					{ new DataMemeberWrapper<DATA_TYPE, arglist...>(memberPtr,
							initargs...) });
		}

		template<typename DATA_TYPE>
		void getMethodMocks(std::vector<DATA_TYPE>& into) const
		{
			for (std::shared_ptr<Destructible> ptr : _methodMocks)
			{
				DATA_TYPE p = dynamic_cast<DATA_TYPE>(ptr.get());
				if (p)
				{
					into.push_back(p);
				}
			}
		}

		VirtualTable<C, baseclasses...>& getOriginalVT()
		{
			VirtualTable<C, baseclasses...>& vt = originalVtHandle.restore();
			return vt;
		}

	private:

		template<typename DATA_TYPE, typename ... arglist>
		class DataMemeberWrapper : public Destructible
		{
		private:
			DATA_TYPE* dataMember;
		public:
			DataMemeberWrapper(DATA_TYPE* dataMem, const arglist& ... initargs) :
					dataMember(dataMem)
			{
				new(dataMember) DATA_TYPE{ initargs ... };
			}

			~DataMemeberWrapper() override
			{
				dataMember->~DATA_TYPE();
			}
		};

		static_assert(sizeof(C) == sizeof(FakeObject<C, baseclasses...>), "This is a problem");

		C& instance;
		typename VirtualTable<C, baseclasses...>::Handle originalVtHandle;
		VirtualTable<C, baseclasses...> _cloneVt;

		std::vector<std::shared_ptr<Destructible>> _methodMocks;
		std::vector<std::shared_ptr<Destructible>> _members;
		std::vector<unsigned int> _offsets;
		InvocationHandlers _invocationHandlers;

		FakeObject<C, baseclasses...>& getFake()
		{
			return reinterpret_cast<FakeObject<C, baseclasses...>&>(instance);
		}

		void bind(const MethodProxy& methodProxy, Destructible* invocationHandler)
		{
			getFake().setMethod(methodProxy.getOffset(), methodProxy.getProxy());
			_methodMocks[methodProxy.getOffset()].reset(invocationHandler);
			_offsets[methodProxy.getOffset()] = methodProxy.getId();
		}

		void bindDtor(const MethodProxy& methodProxy, Destructible* invocationHandler)
		{
			getFake().setDtor(methodProxy.getProxy());
			_methodMocks[methodProxy.getOffset()].reset(invocationHandler);
			_offsets[methodProxy.getOffset()] = methodProxy.getId();
		}

		template<typename DATA_TYPE>
		DATA_TYPE getMethodMock(unsigned int offset)
		{
			std::shared_ptr<Destructible> ptr = _methodMocks[offset];
			return dynamic_cast<DATA_TYPE>(ptr.get());
		}

		template<typename BaseClass>
		void checkMultipleInheritance()
		{
			C* ptr = (C*)(unsigned int)1;
			BaseClass* basePtr = ptr;
			int delta = (unsigned long)basePtr - (unsigned long)ptr;
			if (delta > 0)
			{


				throw std::invalid_argument(std::string("multiple inheritance is not supported"));
			}
		}

		bool isBinded(unsigned int offset)
		{
			std::shared_ptr<Destructible> ptr = _methodMocks[offset];
			return ptr.get() != nullptr;
		}

	};
}

#include <functional>
#include <type_traits>
#include <memory>
#include <iosfwd>
#include <vector>
#include <functional>
#include <tuple>
#include <tuple>

namespace fakeit
{

	template<int N>
	struct apply_func
	{
		template<typename R, typename ... ArgsF, typename ... ArgsT, typename ... Args>
		static R applyTuple(std::function<R(ArgsF& ...)> f, std::tuple<ArgsT...>& t, Args& ... args)
		{
			return apply_func<N - 1>::template applyTuple(f, t, std::get<N - 1>(t), args...);
		}
	};

	template<>
	struct apply_func<0>
	{
		template<typename R, typename ... ArgsF, typename ... ArgsT, typename ... Args>
		static R applyTuple(std::function<R(ArgsF& ...)> f, std::tuple<ArgsT...>&, Args& ... args)
		{
			return f(args...);
		}
	};

	struct TupleDispatcher
	{

		template<typename R, typename ... ArgsF, typename ... ArgsT>
		static R applyTuple(std::function<R(ArgsF& ...)> f, std::tuple<ArgsT...>& t)
		{
			return apply_func<sizeof...(ArgsT)>::template applyTuple(f, t);
		}

		template<typename R, typename ...arglist>
		static R invoke(std::function<R(arglist& ...)> func, const std::tuple<arglist...>& arguments)
		{
			std::tuple<arglist...>& args = const_cast<std::tuple<arglist...>&>(arguments);
			return applyTuple(func, args);
		}

		template<typename TupleType, typename FunctionType>
		static void for_each(TupleType&&, FunctionType&,
				std::integral_constant<size_t, std::tuple_size<typename std::remove_reference<TupleType>::type>::value>)
		{
		}

		template<std::size_t I, typename TupleType, typename FunctionType, typename = typename std::enable_if<
				I != std::tuple_size<typename std::remove_reference<TupleType>::type>::value>::type>
		static void for_each(TupleType&& t, FunctionType& f, std::integral_constant<size_t, I>)
		{
			f(I, std::get<I>(t));
			for_each(std::forward<TupleType>(t), f, std::integral_constant<size_t, I + 1>());
		}

		template<typename TupleType, typename FunctionType>
		static void for_each(TupleType&& t, FunctionType& f)
		{
			for_each(std::forward<TupleType>(t), f, std::integral_constant<size_t, 0>());
		}

		template<typename TupleType1, typename TupleType2, typename FunctionType>
		static void for_each(TupleType1&&, TupleType2&&, FunctionType&,
				std::integral_constant<size_t, std::tuple_size<typename std::remove_reference<TupleType1>::type>::value>)
		{
		}

		template<std::size_t I, typename TupleType1, typename TupleType2, typename FunctionType, typename = typename std::enable_if<
				I != std::tuple_size<typename std::remove_reference<TupleType1>::type>::value>::type>
		static void for_each(TupleType1&& t, TupleType2&& t2, FunctionType& f, std::integral_constant<size_t, I>)
		{
			f(I, std::get<I>(t), std::get<I>(t2));
			for_each(std::forward<TupleType1>(t), std::forward<TupleType2>(t2), f,
					std::integral_constant<size_t, I + 1>());
		}

		template<typename TupleType1, typename TupleType2, typename FunctionType>
		static void for_each(TupleType1&& t, TupleType2&& t2, FunctionType& f)
		{
			for_each(std::forward<TupleType1>(t), std::forward<TupleType2>(t2), f, std::integral_constant<size_t, 0>());
		}
	};
}
namespace fakeit
{

	template<typename R, typename ... arglist>
	struct ActualInvocationHandler : Destructible
	{
		virtual R handleMethodInvocation(ArgumentsTuple<arglist...>& args) = 0;
	};

}

#include <functional>
#include <tuple>
#include <string>
#include <iosfwd>
#include <type_traits>
#include <typeinfo>

namespace fakeit
{

	struct DefaultValueInstatiationException
	{
		virtual ~DefaultValueInstatiationException() = default;

		virtual std::string what() const = 0;
	};


	template<class C>
	struct is_constructible_type
	{
		static const bool value =
				std::is_default_constructible<typename naked_type<C>::type>::value
				&& !std::is_abstract<typename naked_type<C>::type>::value;
	};

	template<class C, class Enable = void>
	struct DefaultValue;

	template<class C>
	struct DefaultValue<C, typename std::enable_if<!is_constructible_type<C>::value>::type>
	{
		static C& value()
		{
			if (std::is_reference<C>::value)
			{
				typename naked_type<C>::type* ptr = nullptr;
				return *ptr;
			}

			class Exception : public DefaultValueInstatiationException
			{
				virtual std::string what() const

				override
				{
					return (std::string("Type ") + std::string(typeid(C).name())
							+ std::string(
							" is not default constructible. Could not instantiate a default return value")).c_str();
				}
			};

			throw Exception();
		}
	};

	template<class C>
	struct DefaultValue<C, typename std::enable_if<is_constructible_type<C>::value>::type>
	{
		static C& value()
		{
			static typename naked_type<C>::type val{};
			return val;
		}
	};


	template<>
	struct DefaultValue<void>
	{
		static void value()
		{
			return;
		}
	};

	template<>
	struct DefaultValue<bool>
	{
		static bool& value()
		{
			static bool value{ false };
			return value;
		}
	};

	template<>
	struct DefaultValue<char>
	{
		static char& value()
		{
			static char value{ 0 };
			return value;
		}
	};

	template<>
	struct DefaultValue<char16_t>
	{
		static char16_t& value()
		{
			static char16_t value{ 0 };
			return value;
		}
	};

	template<>
	struct DefaultValue<char32_t>
	{
		static char32_t& value()
		{
			static char32_t value{ 0 };
			return value;
		}
	};

	template<>
	struct DefaultValue<wchar_t>
	{
		static wchar_t& value()
		{
			static wchar_t value{ 0 };
			return value;
		}
	};

	template<>
	struct DefaultValue<short>
	{
		static short& value()
		{
			static short value{ 0 };
			return value;
		}
	};

	template<>
	struct DefaultValue<int>
	{
		static int& value()
		{
			static int value{ 0 };
			return value;
		}
	};

	template<>
	struct DefaultValue<long>
	{
		static long& value()
		{
			static long value{ 0 };
			return value;
		}
	};

	template<>
	struct DefaultValue<long long>
	{
		static long long& value()
		{
			static long long value{ 0 };
			return value;
		}
	};

	template<>
	struct DefaultValue<std::string>
	{
		static std::string& value()
		{
			static std::string value{};
			return value;
		}
	};

}
namespace fakeit
{

	struct IMatcher : Destructible
	{
		~IMatcher() = default;

		virtual std::string format() const = 0;
	};

	template<typename T>
	struct TypedMatcher : IMatcher
	{
		virtual bool matches(const T& actual) const = 0;
	};

	template<typename T>
	struct TypedMatcherCreator
	{

		virtual ~TypedMatcherCreator() = default;

		virtual TypedMatcher<T>* createMatcher() const = 0;
	};

	template<typename T>
	struct ComparisonMatcherCreator : public TypedMatcherCreator<T>
	{

		virtual ~ComparisonMatcherCreator() = default;

		ComparisonMatcherCreator(const T& arg)
				: _expected(arg)
		{
		}

		struct Matcher : public TypedMatcher<T>
		{
			Matcher(const T& expected)
					: _expected(expected)
			{
			}

			const T _expected;
		};

		const T& _expected;
	};

	namespace internal
	{
		template<typename T>
		struct TypedAnyMatcher : public TypedMatcherCreator<T>
		{

			virtual ~TypedAnyMatcher() = default;

			TypedAnyMatcher()
			{
			}

			struct Matcher : public TypedMatcher<T>
			{
				virtual bool matches(const T&) const override
				{
					return true;
				}

				virtual std::string format() const override
				{
					return "Any";
				}
			};

			virtual TypedMatcher<T>* createMatcher() const override
			{
				return new Matcher();
			}

		};

		template<typename T>
		struct EqMatcherCreator : public ComparisonMatcherCreator<T>
		{

			virtual ~EqMatcherCreator() = default;

			EqMatcherCreator(const T& expected)
					: ComparisonMatcherCreator<T>(expected)
			{
			}

			struct Matcher : public ComparisonMatcherCreator<T>::Matcher
			{
				Matcher(const T& expected)
						: ComparisonMatcherCreator<T>::Matcher(expected)
				{
				}

				virtual std::string format() const override
				{
					return TypeFormatter<T>::format(this->_expected);
				}

				virtual bool matches(const T& actual) const override
				{
					return actual == this->_expected;
				}
			};

			virtual TypedMatcher<T>* createMatcher() const
			{
				return new Matcher(this->_expected);
			}

		};

		template<typename T>
		struct GtMatcherCreator : public ComparisonMatcherCreator<T>
		{

			virtual ~GtMatcherCreator() = default;

			GtMatcherCreator(const T& expected)
					: ComparisonMatcherCreator<T>(expected)
			{
			}

			struct Matcher : public ComparisonMatcherCreator<T>::Matcher
			{
				Matcher(const T& expected)
						: ComparisonMatcherCreator<T>::Matcher(expected)
				{
				}

				virtual bool matches(const T& actual) const override
				{
					return actual > this->_expected;
				}

				virtual std::string format() const override
				{
					return std::string(">") + TypeFormatter<T>::format(this->_expected);
				}
			};

			virtual TypedMatcher<T>* createMatcher() const override
			{
				return new Matcher(this->_expected);
			}
		};

		template<typename T>
		struct GeMatcherCreator : public ComparisonMatcherCreator<T>
		{

			virtual ~GeMatcherCreator() = default;

			GeMatcherCreator(const T& expected)
					: ComparisonMatcherCreator<T>(expected)
			{
			}

			struct Matcher : public ComparisonMatcherCreator<T>::Matcher
			{
				Matcher(const T& expected)
						: ComparisonMatcherCreator<T>::Matcher(expected)
				{
				}

				virtual bool matches(const T& actual) const override
				{
					return actual >= this->_expected;
				}

				virtual std::string format() const override
				{
					return std::string(">=") + TypeFormatter<T>::format(this->_expected);
				}
			};

			virtual TypedMatcher<T>* createMatcher() const override
			{
				return new Matcher(this->_expected);
			}
		};

		template<typename T>
		struct LtMatcherCreator : public ComparisonMatcherCreator<T>
		{

			virtual ~LtMatcherCreator() = default;

			LtMatcherCreator(const T& expected)
					: ComparisonMatcherCreator<T>(expected)
			{
			}

			struct Matcher : public ComparisonMatcherCreator<T>::Matcher
			{
				Matcher(const T& expected)
						: ComparisonMatcherCreator<T>::Matcher(expected)
				{
				}

				virtual bool matches(const T& actual) const override
				{
					return actual < this->_expected;
				}

				virtual std::string format() const override
				{
					return std::string("<") + TypeFormatter<T>::format(this->_expected);
				}
			};

			virtual TypedMatcher<T>* createMatcher() const override
			{
				return new Matcher(this->_expected);
			}

		};

		template<typename T>
		struct LeMatcherCreator : public ComparisonMatcherCreator<T>
		{

			virtual ~LeMatcherCreator() = default;

			LeMatcherCreator(const T& expected)
					: ComparisonMatcherCreator<T>(expected)
			{
			}

			struct Matcher : public ComparisonMatcherCreator<T>::Matcher
			{
				Matcher(const T& expected)
						: ComparisonMatcherCreator<T>::Matcher(expected)
				{
				}

				virtual bool matches(const T& actual) const override
				{
					return actual <= this->_expected;
				}

				virtual std::string format() const override
				{
					return std::string("<=") + TypeFormatter<T>::format(this->_expected);
				}
			};

			virtual TypedMatcher<T>* createMatcher() const override
			{
				return new Matcher(this->_expected);
			}

		};

		template<typename T>
		struct NeMatcherCreator : public ComparisonMatcherCreator<T>
		{

			virtual ~NeMatcherCreator() = default;

			NeMatcherCreator(const T& expected)
					: ComparisonMatcherCreator<T>(expected)
			{
			}

			struct Matcher : public ComparisonMatcherCreator<T>::Matcher
			{
				Matcher(const T& expected)
						: ComparisonMatcherCreator<T>::Matcher(expected)
				{
				}

				virtual bool matches(const T& actual) const override
				{
					return actual != this->_expected;
				}

				virtual std::string format() const override
				{
					return std::string("!=") + TypeFormatter<T>::format(this->_expected);
				}

			};

			virtual TypedMatcher<T>* createMatcher() const override
			{
				return new Matcher(this->_expected);
			}

		};
	}

	struct AnyMatcher
	{
	} static _;

	template<typename T>
	internal::TypedAnyMatcher<T> Any()
	{
		internal::TypedAnyMatcher<T> rv;
		return rv;
	}

	template<typename T>
	internal::EqMatcherCreator<T> Eq(const T& arg)
	{
		internal::EqMatcherCreator<T> rv(arg);
		return rv;
	}

	template<typename T>
	internal::GtMatcherCreator<T> Gt(const T& arg)
	{
		internal::GtMatcherCreator<T> rv(arg);
		return rv;
	}

	template<typename T>
	internal::GeMatcherCreator<T> Ge(const T& arg)
	{
		internal::GeMatcherCreator<T> rv(arg);
		return rv;
	}

	template<typename T>
	internal::LtMatcherCreator<T> Lt(const T& arg)
	{
		internal::LtMatcherCreator<T> rv(arg);
		return rv;
	}

	template<typename T>
	internal::LeMatcherCreator<T> Le(const T& arg)
	{
		internal::LeMatcherCreator<T> rv(arg);
		return rv;
	}

	template<typename T>
	internal::NeMatcherCreator<T> Ne(const T& arg)
	{
		internal::NeMatcherCreator<T> rv(arg);
		return rv;
	}

}

namespace fakeit
{

	template<typename ... arglist>
	struct ArgumentsMatcherInvocationMatcher : public ActualInvocation<arglist...>::Matcher
	{

		virtual ~ArgumentsMatcherInvocationMatcher()
		{
			for (unsigned int i = 0; i < _matchers.size(); i++)
				delete _matchers[i];
		}

		ArgumentsMatcherInvocationMatcher(const std::vector<Destructible*>& args)
				: _matchers(args)
		{
		}

		virtual bool matches(ActualInvocation<arglist...>& invocation) override
		{
			if (invocation.getActualMatcher() == this)
				return true;
			return matches(invocation.getActualArguments());
		}

		virtual std::string format() const override
		{
			std::ostringstream out;
			out << "(";
			for (unsigned int i = 0; i < _matchers.size(); i++)
			{
				if (i > 0) out << ", ";
				IMatcher* m = dynamic_cast<IMatcher*>(_matchers[i]);
				out << m->format();
			}
			out << ")";
			return out.str();
		}

	private:

		struct MatchingLambda
		{
			MatchingLambda(const std::vector<Destructible*>& matchers)
					: _matchers(matchers)
			{
			}

			template<typename A>
			void operator()(int index, A& actualArg)
			{
				TypedMatcher<typename naked_type<A>::type>* matcher =
						dynamic_cast<TypedMatcher<typename naked_type<A>::type>*>(_matchers[index]);
				if (_matching)
					_matching = matcher->matches(actualArg);
			}

			bool isMatching()
			{
				return _matching;
			}

		private:
			bool _matching = true;
			const std::vector<Destructible*>& _matchers;
		};

		virtual bool matches(ArgumentsTuple<arglist...>& actualArguments)
		{
			MatchingLambda l(_matchers);
			fakeit::TupleDispatcher::for_each(actualArguments, l);
			return l.isMatching();
		}

		const std::vector<Destructible*> _matchers;
	};


	template<typename ... arglist>
	struct UserDefinedInvocationMatcher : ActualInvocation<arglist...>::Matcher
	{
		virtual ~UserDefinedInvocationMatcher() = default;

		UserDefinedInvocationMatcher(std::function<bool(arglist& ...)> match)
				: matcher{ match }
		{
		}

		virtual bool matches(ActualInvocation<arglist...>& invocation) override
		{
			if (invocation.getActualMatcher() == this)
				return true;
			return matches(invocation.getActualArguments());
		}

		virtual std::string format() const override
		{
			return { "( user defined matcher )" };
		}

	private:
		virtual bool matches(ArgumentsTuple<arglist...>& actualArguments)
		{
			return TupleDispatcher::invoke<bool, typename tuple_arg<arglist>::type...>(matcher, actualArguments);
		}

		const std::function<bool(arglist& ...)> matcher;
	};

	template<typename ... arglist>
	struct DefaultInvocationMatcher : public ActualInvocation<arglist...>::Matcher
	{

		virtual ~DefaultInvocationMatcher() = default;

		DefaultInvocationMatcher()
		{
		}

		virtual bool matches(ActualInvocation<arglist...>& invocation) override
		{
			return matches(invocation.getActualArguments());
		}

		virtual std::string format() const override
		{
			return { "( Any arguments )" };
		}

	private:

		virtual bool matches(const ArgumentsTuple<arglist...>&)
		{
			return true;
		}
	};

}

namespace fakeit
{


	template<typename R, typename ... arglist>
	class RecordedMethodBody
			: public MethodInvocationHandler<R, arglist...>,
			  public ActualInvocationsSource,
			  public ActualInvocationsContainer
	{

		struct MatchedInvocationHandler : ActualInvocationHandler<R, arglist...>
		{

			virtual ~MatchedInvocationHandler() = default;

			MatchedInvocationHandler(typename ActualInvocation<arglist...>::Matcher* matcher,
					ActualInvocationHandler<R, arglist...>* invocationHandler) :
					_matcher{ matcher }, _invocationHandler{ invocationHandler }
			{
			}

			virtual R handleMethodInvocation(ArgumentsTuple<arglist...>& args) override
			{
				Destructible& destructable = *_invocationHandler;
				ActualInvocationHandler<R, arglist...>& invocationHandler = dynamic_cast<ActualInvocationHandler<R, arglist...>&>(destructable);
				return invocationHandler.handleMethodInvocation(args);
			}

			typename ActualInvocation<arglist...>::Matcher& getMatcher() const
			{
				Destructible& destructable = *_matcher;
				typename ActualInvocation<arglist...>::Matcher& matcher = dynamic_cast<typename ActualInvocation<arglist...>::Matcher&>(destructable);
				return matcher;
			}

		private:
			std::shared_ptr<Destructible> _matcher;
			std::shared_ptr<Destructible> _invocationHandler;
		};


		FakeitContext& _fakeit;
		MethodInfo _method;

		std::vector<std::shared_ptr<Destructible>> _invocationHandlers;
		std::vector<std::shared_ptr<Destructible>> _actualInvocations;

		MatchedInvocationHandler* buildMatchedInvocationHandler(
				typename ActualInvocation<arglist...>::Matcher* invocationMatcher,
				ActualInvocationHandler<R, arglist...>* invocationHandler)
		{
			return new MatchedInvocationHandler(invocationMatcher, invocationHandler);
		}

		MatchedInvocationHandler* getInvocationHandlerForActualArgs(ActualInvocation<arglist...>& invocation)
		{
			for (auto i = _invocationHandlers.rbegin(); i != _invocationHandlers.rend(); ++i)
			{
				std::shared_ptr<Destructible> curr = *i;
				Destructible& destructable = *curr;
				MatchedInvocationHandler& im = asMatchedInvocationHandler(destructable);
				if (im.getMatcher().matches(invocation))
				{
					return &im;
				}
			}
			return nullptr;
		}

		MatchedInvocationHandler& asMatchedInvocationHandler(Destructible& destructable)
		{
			MatchedInvocationHandler& im = dynamic_cast<MatchedInvocationHandler&>(destructable);
			return im;
		}

		ActualInvocation<arglist...>& asActualInvocation(Destructible& destructable) const
		{
			ActualInvocation<arglist...>& invocation = dynamic_cast<ActualInvocation<arglist...>&>(destructable);
			return invocation;
		}

	public:

		RecordedMethodBody(FakeitContext& fakeit, std::string name) :
				_fakeit(fakeit), _method{ MethodInfo::nextMethodOrdinal(), name }
		{
		}

		virtual ~RecordedMethodBody() NO_THROWS
		{
		}

		MethodInfo& getMethod()
		{
			return _method;
		}

		bool isOfMethod(MethodInfo& method)
		{

			return method.id() == _method.id();
		}

		void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher* matcher,
				ActualInvocationHandler<R, arglist...>* invocationHandler)
		{
			ActualInvocationHandler<R, arglist...>* mock = buildMatchedInvocationHandler(matcher, invocationHandler);
			std::shared_ptr<Destructible> destructable{ mock };
			_invocationHandlers.push_back(destructable);
		}

		void reset()
		{
			_invocationHandlers.clear();
			_actualInvocations.clear();
		}

		void clear() override
		{
			_actualInvocations.clear();
		}

		R handleMethodInvocation(const typename fakeit::production_arg<arglist>::type... args) override
		{
			unsigned int ordinal = Invocation::nextInvocationOrdinal();
			MethodInfo& method = this->getMethod();
			auto actualInvocation = new ActualInvocation<arglist...>(ordinal, method,
					std::forward<const typename fakeit::production_arg<arglist>::type>(args)...);


			std::shared_ptr<Destructible> actualInvocationDtor{ actualInvocation };

			auto invocationHandler = getInvocationHandlerForActualArgs(*actualInvocation);
			if (invocationHandler)
			{
				auto& matcher = invocationHandler->getMatcher();
				actualInvocation->setActualMatcher(&matcher);
				_actualInvocations.push_back(actualInvocationDtor);
				try
				{
					return invocationHandler->handleMethodInvocation(actualInvocation->getActualArguments());
				}
				catch (NoMoreRecordedActionException&)
				{
				}
			}

			UnexpectedMethodCallEvent event(UnexpectedType::Unmatched, *actualInvocation);
			_fakeit.handle(event);
			std::string format{ _fakeit.format(event) };
			UnexpectedMethodCallException e(format);
			throw e;
		}

		void scanActualInvocations(const std::function<void(ActualInvocation<arglist...>&)>& scanner)
		{
			for (auto destructablePtr : _actualInvocations)
			{
				ActualInvocation<arglist...>& invocation = asActualInvocation(*destructablePtr);
				scanner(invocation);
			}
		}

		void getActualInvocations(std::unordered_set<Invocation*>& into) const override
		{
			for (auto destructablePtr : _actualInvocations)
			{
				Invocation& invocation = asActualInvocation(*destructablePtr);
				into.insert(&invocation);
			}
		}

		void setMethodDetails(const std::string& mockName, const std::string& methodName)
		{
			const std::string fullName{ mockName + "." + methodName };
			_method.setName(fullName);
		}

	};

}

#include <functional>
#include <type_traits>
#include <stdexcept>
#include <utility>
#include <functional>
#include <type_traits>

namespace fakeit
{

	struct Quantity
	{
		Quantity(const int q) :
				quantity(q)
		{
		}

		const int quantity;
	} static Once(1);

	template<typename R>
	struct Quantifier : public Quantity
	{
		Quantifier(const int q, const R& val) :
				Quantity(q), value(val)
		{
		}

		const R& value;
	};

	template<>
	struct Quantifier<void> : public Quantity
	{
		explicit Quantifier(const int q) :
				Quantity(q)
		{
		}
	};

	struct QuantifierFunctor : public Quantifier<void>
	{
		QuantifierFunctor(const int q) :
				Quantifier<void>(q)
		{
		}

		template<typename R>
		Quantifier<R> operator()(const R& value)
		{
			return Quantifier<R>(quantity, value);
		}
	};

	template<int q>
	struct Times : public Quantity
	{

		Times<q>() : Quantity(q)
		{
		}

		template<typename R>
		static Quantifier<R> of(const R& value)
		{
			return Quantifier<R>(q, value);
		}

		static Quantifier<void> Void()
		{
			return Quantifier<void>(q);
		}
	};

#if defined (__GNUG__) || (_MSC_VER >= 1900)

	inline QuantifierFunctor operator
	""

	_Times(unsigned long long n)
	{
		return QuantifierFunctor((int)n);
	}

	inline QuantifierFunctor operator
	""

	_Time(unsigned long long n)
	{
		if (n != 1)
			throw std::invalid_argument("Only 1_Time is supported. Use X_Times (with s) if X is bigger than 1");
		return QuantifierFunctor((int)n);
	}

#endif

}

#include <functional>
#include <atomic>
#include <tuple>
#include <type_traits>


namespace fakeit
{

	template<typename R, typename ... arglist>
	struct Action : Destructible
	{
		virtual R invoke(const ArgumentsTuple<arglist...>&) = 0;

		virtual bool isDone() = 0;
	};

	template<typename R, typename ... arglist>
	struct Repeat : Action<R, arglist...>
	{
		virtual ~Repeat() = default;

		Repeat(std::function<R(typename fakeit::test_arg<arglist>::type...)> func) :
				f(func), times(1)
		{
		}

		Repeat(std::function<R(typename fakeit::test_arg<arglist>::type...)> func, long t) :
				f(func), times(t)
		{
		}

		virtual R invoke(const ArgumentsTuple<arglist...>& args) override
		{
			times--;
			return TupleDispatcher::invoke<R, arglist...>(f, args);
		}

		virtual bool isDone() override
		{
			return times == 0;
		}

	private:
		std::function<R(typename fakeit::test_arg<arglist>::type...)> f;
		long times;
	};

	template<typename R, typename ... arglist>
	struct RepeatForever : public Action<R, arglist...>
	{

		virtual ~RepeatForever() = default;

		RepeatForever(std::function<R(typename fakeit::test_arg<arglist>::type...)> func) :
				f(func)
		{
		}

		virtual R invoke(const ArgumentsTuple<arglist...>& args) override
		{
			return TupleDispatcher::invoke<R, arglist...>(f, args);
		}

		virtual bool isDone() override
		{
			return false;
		}

	private:
		std::function<R(typename fakeit::test_arg<arglist>::type...)> f;
	};

	template<typename R, typename ... arglist>
	struct ReturnDefaultValue : public Action<R, arglist...>
	{
		virtual ~ReturnDefaultValue() = default;

		virtual R invoke(const ArgumentsTuple<arglist...>&) override
		{
			return DefaultValue<R>::value();
		}

		virtual bool isDone() override
		{
			return false;
		}
	};

	template<typename R, typename ... arglist>
	struct ReturnDelegateValue : public Action<R, arglist...>
	{

		ReturnDelegateValue(std::function<R(const typename fakeit::test_arg<arglist>::type...)> delegate) : _delegate(
				delegate)
		{
		}

		virtual ~ReturnDelegateValue() = default;

		virtual R invoke(const ArgumentsTuple<arglist...>& args) override
		{
			return TupleDispatcher::invoke<R, arglist...>(_delegate, args);
		}

		virtual bool isDone() override
		{
			return false;
		}

	private:
		std::function<R(const typename fakeit::test_arg<arglist>::type...)> _delegate;
	};

}

namespace fakeit
{

	template<typename R, typename ... arglist>
	struct MethodStubbingProgress
	{

		virtual ~MethodStubbingProgress() THROWS
		{
		}

		template<typename U = R>
		typename std::enable_if<!std::is_reference<U>::value, MethodStubbingProgress<R, arglist...>&>::type
		Return(const R& r)
		{
			return Do([r](const typename fakeit::test_arg<arglist>::type...) -> R
			{ return r; });
		}

		template<typename U = R>
		typename std::enable_if<std::is_reference<U>::value, MethodStubbingProgress<R, arglist...>&>::type
		Return(const R& r)
		{
			return Do([&r](const typename fakeit::test_arg<arglist>::type...) -> R
			{ return r; });
		}

		MethodStubbingProgress<R, arglist...>&
		Return(const Quantifier<R>& q)
		{
			const R& value = q.value;
			auto method = [value](const arglist& ...) -> R
			{ return value; };
			return DoImpl(new Repeat<R, arglist...>(method, q.quantity));
		}

		template<typename first, typename second, typename ... tail>
		MethodStubbingProgress<R, arglist...>&
		Return(const first& f, const second& s, const tail& ... t)
		{
			Return(f);
			return Return(s, t...);
		}


		template<typename U = R>
		typename std::enable_if<!std::is_reference<U>::value, void>::type
		AlwaysReturn(const R& r)
		{
			return AlwaysDo([r](const typename fakeit::test_arg<arglist>::type...) -> R
			{ return r; });
		}

		template<typename U = R>
		typename std::enable_if<std::is_reference<U>::value, void>::type
		AlwaysReturn(const R& r)
		{
			return AlwaysDo([&r](const typename fakeit::test_arg<arglist>::type...) -> R
			{ return r; });
		}

		MethodStubbingProgress<R, arglist...>&
		Return()
		{
			return Do([](const typename fakeit::test_arg<arglist>::type...) -> R
			{ return DefaultValue<R>::value(); });
		}

		void AlwaysReturn()
		{
			return AlwaysDo([](const typename fakeit::test_arg<arglist>::type...) -> R
			{ return DefaultValue<R>::value(); });
		}

		template<typename E>
		MethodStubbingProgress<R, arglist...>& Throw(const E& e)
		{
			return Do([e](const typename fakeit::test_arg<arglist>::type...) -> R
			{ throw e; });
		}

		template<typename E>
		MethodStubbingProgress<R, arglist...>&
		Throw(const Quantifier<E>& q)
		{
			const E& value = q.value;
			auto method = [value](const arglist& ...) -> R
			{ throw value; };
			return DoImpl(new Repeat<R, arglist...>(method, q.quantity));
		}

		template<typename first, typename second, typename ... tail>
		MethodStubbingProgress<R, arglist...>&
		Throw(const first& f, const second& s, const tail& ... t)
		{
			Throw(f);
			return Throw(s, t...);
		}

		template<typename E>
		void AlwaysThrow(const E& e)
		{
			return AlwaysDo([e](const typename fakeit::test_arg<arglist>::type...) -> R
			{ throw e; });
		}

		virtual MethodStubbingProgress<R, arglist...>&
		Do(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method)
		{
			return DoImpl(new Repeat<R, arglist...>(method));
		}

		template<typename F>
		MethodStubbingProgress<R, arglist...>&
		Do(const Quantifier<F>& q)
		{
			return DoImpl(new Repeat<R, arglist...>(q.value, q.quantity));
		}

		template<typename first, typename second, typename ... tail>
		MethodStubbingProgress<R, arglist...>&
		Do(const first& f, const second& s, const tail& ... t)
		{
			Do(f);
			return Do(s, t...);
		}

		virtual void AlwaysDo(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method)
		{
			DoImpl(new RepeatForever<R, arglist...>(method));
		}

	protected:

		virtual MethodStubbingProgress<R, arglist...>& DoImpl(Action<R, arglist...>* action) = 0;

	private:
		MethodStubbingProgress& operator=(const MethodStubbingProgress& other) = delete;
	};


	template<typename ... arglist>
	struct MethodStubbingProgress<void, arglist...>
	{

		virtual ~MethodStubbingProgress() THROWS
		{
		}

		MethodStubbingProgress<void, arglist...>& Return()
		{
			auto lambda = [](const typename fakeit::test_arg<arglist>::type...) -> void
			{
				return DefaultValue<void>::value();
			};
			return Do(lambda);
		}

		virtual MethodStubbingProgress<void, arglist...>& Do(
				std::function<void(const typename fakeit::test_arg<arglist>::type...)> method)
		{
			return DoImpl(new Repeat<void, arglist...>(method));
		}


		void AlwaysReturn()
		{
			return AlwaysDo([](const typename fakeit::test_arg<arglist>::type...) -> void
			{ return DefaultValue<void>::value(); });
		}

		MethodStubbingProgress<void, arglist...>&
		Return(const Quantifier<void>& q)
		{
			auto method = [](const arglist& ...) -> void
			{ return DefaultValue<void>::value(); };
			return DoImpl(new Repeat<void, arglist...>(method, q.quantity));
		}

		template<typename E>
		MethodStubbingProgress<void, arglist...>& Throw(const E& e)
		{
			return Do([e](const typename fakeit::test_arg<arglist>::type...) -> void
			{ throw e; });
		}

		template<typename E>
		MethodStubbingProgress<void, arglist...>&
		Throw(const Quantifier<E>& q)
		{
			const E& value = q.value;
			auto method = [value](const typename fakeit::test_arg<arglist>::type...) -> void
			{ throw value; };
			return DoImpl(new Repeat<void, arglist...>(method, q.quantity));
		}

		template<typename first, typename second, typename ... tail>
		MethodStubbingProgress<void, arglist...>&
		Throw(const first& f, const second& s, const tail& ... t)
		{
			Throw(f);
			return Throw(s, t...);
		}

		template<typename E>
		void AlwaysThrow(const E e)
		{
			return AlwaysDo([e](const typename fakeit::test_arg<arglist>::type...) -> void
			{ throw e; });
		}

		template<typename F>
		MethodStubbingProgress<void, arglist...>&
		Do(const Quantifier<F>& q)
		{
			return DoImpl(new Repeat<void, arglist...>(q.value, q.quantity));
		}

		template<typename first, typename second, typename ... tail>
		MethodStubbingProgress<void, arglist...>&
		Do(const first& f, const second& s, const tail& ... t)
		{
			Do(f);
			return Do(s, t...);
		}

		virtual void AlwaysDo(std::function<void(const typename fakeit::test_arg<arglist>::type...)> method)
		{
			DoImpl(new RepeatForever<void, arglist...>(method));
		}

	protected:

		virtual MethodStubbingProgress<void, arglist...>& DoImpl(Action<void, arglist...>* action) = 0;

	private:
		MethodStubbingProgress& operator=(const MethodStubbingProgress& other) = delete;
	};


}

#include <vector>
#include <functional>

namespace fakeit
{

	class Finally
	{
	private:
		std::function<void()> _finallyClause;

		Finally(const Finally&);

		Finally& operator=(const Finally&);

	public:
		explicit Finally(std::function<void()> f) :
				_finallyClause(f)
		{
		}

		~Finally()
		{
			_finallyClause();
		}
	};
}

namespace fakeit
{


	template<typename R, typename ... arglist>
	struct ActionSequence : ActualInvocationHandler<R, arglist...>
	{

		ActionSequence()
		{
			clear();
		}

		void AppendDo(Action<R, arglist...>* action)
		{
			append(action);
		}

		virtual R handleMethodInvocation(ArgumentsTuple<arglist...>& args) override
		{
			std::shared_ptr<Destructible> destructablePtr = _recordedActions.front();
			Destructible& destructable = *destructablePtr;
			Action<R, arglist...>& action = dynamic_cast<Action<R, arglist...>&>(destructable);
			std::function<void()> finallyClause = [&]() -> void
			{
				if (action.isDone())
					_recordedActions.erase(_recordedActions.begin());
			};
			Finally onExit(finallyClause);
			return action.invoke(args);
		}

	private:

		struct NoMoreRecordedAction : Action<R, arglist...>
		{


			virtual R invoke(const ArgumentsTuple<arglist...>&) override
			{
				throw NoMoreRecordedActionException();
			}

			virtual bool isDone() override
			{
				return false;
			}
		};

		void append(Action<R, arglist...>* action)
		{
			std::shared_ptr<Destructible> destructable{ action };
			_recordedActions.insert(_recordedActions.end() - 1, destructable);
		}

		void clear()
		{
			_recordedActions.clear();
			auto actionPtr = std::shared_ptr<Destructible>{ new NoMoreRecordedAction() };
			_recordedActions.push_back(actionPtr);
		}

		std::vector<std::shared_ptr<Destructible>> _recordedActions;
	};

}

namespace fakeit
{

	template<typename C, typename DATA_TYPE>
	class DataMemberStubbingRoot
	{
	private:

	public:
		DataMemberStubbingRoot(const DataMemberStubbingRoot&) = default;

		DataMemberStubbingRoot() = default;

		void operator=(const DATA_TYPE&)
		{
		}
	};

}

#include <functional>
#include <utility>
#include <type_traits>
#include <tuple>
#include <memory>
#include <vector>
#include <unordered_set>
#include <set>
#include <iosfwd>

namespace fakeit
{

	struct Xaction
	{
		virtual void commit() = 0;
	};
}

namespace fakeit
{


	template<typename R, typename ... arglist>
	struct SpyingContext : Xaction
	{
		virtual void appendAction(Action<R, arglist...>* action) = 0;

		virtual std::function<R(arglist& ...)> getOriginalMethod() = 0;
	};
}
namespace fakeit
{


	template<typename R, typename ... arglist>
	struct StubbingContext : public Xaction
	{
		virtual void appendAction(Action<R, arglist...>* action) = 0;
	};
}

#include <functional>
#include <type_traits>
#include <tuple>
#include <memory>
#include <vector>
#include <unordered_set>


namespace fakeit
{

	template<unsigned int index, typename ... arglist>
	class MatchersCollector
	{

		std::vector<Destructible*>& _matchers;

	public:


		template<std::size_t N>
		using ArgType = typename std::tuple_element<N, std::tuple<arglist...>>::type;

		template<std::size_t N>
		using NakedArgType = typename naked_type<ArgType<index>>::type;

		template<std::size_t N>
		using ArgMatcherCreatorType = decltype(std::declval<TypedMatcherCreator<NakedArgType<N>>>());

		MatchersCollector(std::vector<Destructible*>& matchers)
				: _matchers(matchers)
		{
		}

		void CollectMatchers()
		{
		}

		template<typename Head>
		typename std::enable_if<
				std::is_constructible<NakedArgType<index>, Head>::value, void>
		::type CollectMatchers(const Head& value)
		{

			TypedMatcher<NakedArgType<index>>* d = Eq<NakedArgType<index>>(value).createMatcher();
			_matchers.push_back(d);
		}

		template<typename Head, typename ...Tail>
		typename std::enable_if<
				std::is_constructible<NakedArgType<index>, Head>::value, void>
		::type CollectMatchers(const Head& head, const Tail& ... tail)
		{
			CollectMatchers(head);
			MatchersCollector<index + 1, arglist...> c(_matchers);
			c.CollectMatchers(tail...);
		}

		template<typename Head>
		typename std::enable_if<
				std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void>
		::type CollectMatchers(const Head& creator)
		{
			TypedMatcher<NakedArgType<index>>* d = creator.createMatcher();
			_matchers.push_back(d);
		}

		template<typename Head, typename ...Tail>

		typename std::enable_if<
				std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void>
		::type CollectMatchers(const Head& head, const Tail& ... tail)
		{
			CollectMatchers(head);
			MatchersCollector<index + 1, arglist...> c(_matchers);
			c.CollectMatchers(tail...);
		}

		template<typename Head>
		typename std::enable_if<
				std::is_same<AnyMatcher, Head>::value, void>
		::type CollectMatchers(const Head&)
		{
			TypedMatcher<NakedArgType<index>>* d = Any<NakedArgType<index>>().createMatcher();
			_matchers.push_back(d);
		}

		template<typename Head, typename ...Tail>
		typename std::enable_if<
				std::is_same<AnyMatcher, Head>::value, void>
		::type CollectMatchers(const Head& head, const Tail& ... tail)
		{
			CollectMatchers(head);
			MatchersCollector<index + 1, arglist...> c(_matchers);
			c.CollectMatchers(tail...);
		}

	};

}

namespace fakeit
{

	template<typename R, typename ... arglist>
	class MethodMockingContext :
			public Sequence,
			public ActualInvocationsSource,
			public virtual StubbingContext<R, arglist...>,
			public virtual SpyingContext<R, arglist...>,
			private Invocation::Matcher
	{
	public:

		struct Context : Destructible
		{


			virtual typename std::function<R(arglist& ...)> getOriginalMethod() = 0;

			virtual std::string getMethodName() = 0;

			virtual void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher* matcher,
					ActualInvocationHandler<R, arglist...>* invocationHandler) = 0;

			virtual void scanActualInvocations(const std::function<void(ActualInvocation<arglist...>&)>& scanner) = 0;

			virtual void setMethodDetails(std::string mockName, std::string methodName) = 0;

			virtual bool isOfMethod(MethodInfo& method) = 0;

			virtual ActualInvocationsSource& getInvolvedMock() = 0;
		};

	private:
		class Implementation
		{

			Context* _stubbingContext;
			ActionSequence<R, arglist...>* _recordedActionSequence;
			typename ActualInvocation<arglist...>::Matcher* _invocationMatcher;
			bool _commited;

			Context& getStubbingContext() const
			{
				return *_stubbingContext;
			}

		public:

			Implementation(Context* stubbingContext)
					: _stubbingContext(stubbingContext),
					  _recordedActionSequence(new ActionSequence<R, arglist...>()),
					  _invocationMatcher
							  {
									  new DefaultInvocationMatcher<arglist...>() }, _commited(false)
			{
			}

			~Implementation()
			{
				delete _stubbingContext;
				if (!_commited)
				{

					delete _recordedActionSequence;
					delete _invocationMatcher;
				}
			}

			ActionSequence<R, arglist...>& getRecordedActionSequence()
			{
				return *_recordedActionSequence;
			}

			std::string format() const
			{
				std::string s = getStubbingContext().getMethodName();
				s += _invocationMatcher->format();
				return s;
			}

			void getActualInvocations(std::unordered_set<Invocation*>& into) const
			{
				auto scanner = [&](ActualInvocation<arglist...>& a)
				{
					if (_invocationMatcher->matches(a))
					{
						into.insert(&a);
					}
				};
				getStubbingContext().scanActualInvocations(scanner);
			}


			bool matches(Invocation& invocation)
			{
				MethodInfo& actualMethod = invocation.getMethod();
				if (!getStubbingContext().isOfMethod(actualMethod))
				{
					return false;
				}

				ActualInvocation<arglist...>& actualInvocation = dynamic_cast<ActualInvocation<arglist...>&>(invocation);
				return _invocationMatcher->matches(actualInvocation);
			}

			void commit()
			{
				getStubbingContext().addMethodInvocationHandler(_invocationMatcher, _recordedActionSequence);
				_commited = true;
			}

			void appendAction(Action<R, arglist...>* action)
			{
				getRecordedActionSequence().AppendDo(action);
			}

			void setMethodBodyByAssignment(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method)
			{
				appendAction(new RepeatForever<R, arglist...>(method));
				commit();
			}

			void setMethodDetails(std::string mockName, std::string methodName)
			{
				getStubbingContext().setMethodDetails(mockName, methodName);
			}

			void getInvolvedMocks(std::vector<ActualInvocationsSource*>& into) const
			{
				into.push_back(&getStubbingContext().getInvolvedMock());
			}

			typename std::function<R(arglist& ...)> getOriginalMethod()
			{
				return getStubbingContext().getOriginalMethod();
			}

			void setInvocationMatcher(typename ActualInvocation<arglist...>::Matcher* matcher)
			{
				delete _invocationMatcher;
				_invocationMatcher = matcher;
			}
		};

	protected:

		MethodMockingContext(Context* stubbingContext)
				: _impl{ new Implementation(stubbingContext) }
		{
		}

		MethodMockingContext(MethodMockingContext&) = default;


		MethodMockingContext(MethodMockingContext&& other)
				: _impl(std::move(other._impl))
		{
		}

		virtual ~MethodMockingContext() NO_THROWS
		{
		}

		std::string format() const override
		{
			return _impl->format();
		}

		unsigned int size() const override
		{
			return 1;
		}


		void getInvolvedMocks(std::vector<ActualInvocationsSource*>& into) const override
		{
			_impl->getInvolvedMocks(into);
		}

		void getExpectedSequence(std::vector<Invocation::Matcher*>& into) const override
		{
			const Invocation::Matcher* b = this;
			Invocation::Matcher* c = const_cast<Invocation::Matcher*>(b);
			into.push_back(c);
		}


		void getActualInvocations(std::unordered_set<Invocation*>& into) const override
		{
			_impl->getActualInvocations(into);
		}


		bool matches(Invocation& invocation) override
		{
			return _impl->matches(invocation);
		}

		void commit() override
		{
			_impl->commit();
		}

		void setMethodDetails(std::string mockName, std::string methodName)
		{
			_impl->setMethodDetails(mockName, methodName);
		}

		void setMatchingCriteria(std::function<bool(arglist& ...)> predicate)
		{
			typename ActualInvocation<arglist...>::Matcher* matcher{
					new UserDefinedInvocationMatcher<arglist...>(predicate) };
			_impl->setInvocationMatcher(matcher);
		}

		void setMatchingCriteria(const std::vector<Destructible*>& matchers)
		{
			typename ActualInvocation<arglist...>::Matcher* matcher{
					new ArgumentsMatcherInvocationMatcher<arglist...>(matchers) };
			_impl->setInvocationMatcher(matcher);
		}


		void appendAction(Action<R, arglist...>* action) override
		{
			_impl->appendAction(action);
		}

		void setMethodBodyByAssignment(std::function<R(const typename fakeit::test_arg<arglist>::type...)> method)
		{
			_impl->setMethodBodyByAssignment(method);
		}

		template<class ...matcherCreators, class = typename std::enable_if<
				sizeof...(matcherCreators) == sizeof...(arglist)>::type>
		void setMatchingCriteria(const matcherCreators& ... matcherCreator)
		{
			std::vector<Destructible*> matchers;

			MatchersCollector<0, arglist...> c(matchers);
			c.CollectMatchers(matcherCreator...);

			MethodMockingContext<R, arglist...>::setMatchingCriteria(matchers);
		}

	private:

		typename std::function<R(arglist& ...)> getOriginalMethod() override
		{
			return _impl->getOriginalMethod();
		}

		std::shared_ptr<Implementation> _impl;
	};

	template<typename R, typename ... arglist>
	class MockingContext :
			public MethodMockingContext<R, arglist...>
	{
		MockingContext& operator=(const MockingContext&) = delete;

	public:

		MockingContext(typename MethodMockingContext<R, arglist...>::Context* stubbingContext)
				: MethodMockingContext<R, arglist...>(stubbingContext)
		{
		}

		MockingContext(MockingContext&) = default;

		MockingContext(MockingContext&& other)
				: MethodMockingContext<R, arglist...>(std::move(other))
		{
		}

		MockingContext<R, arglist...>& setMethodDetails(std::string mockName, std::string methodName)
		{
			MethodMockingContext<R, arglist...>::setMethodDetails(mockName, methodName);
			return *this;
		}

		MockingContext<R, arglist...>& Using(const arglist& ... args)
		{
			MethodMockingContext<R, arglist...>::setMatchingCriteria(args...);
			return *this;
		}

		template<class ...arg_matcher>
		MockingContext<R, arglist...>& Using(const arg_matcher& ... arg_matchers)
		{
			MethodMockingContext<R, arglist...>::setMatchingCriteria(arg_matchers...);
			return *this;
		}

		MockingContext<R, arglist...>& Matching(std::function<bool(arglist& ...)> matcher)
		{
			MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher);
			return *this;
		}

		MockingContext<R, arglist...>& operator()(const arglist& ... args)
		{
			MethodMockingContext<R, arglist...>::setMatchingCriteria(args...);
			return *this;
		}

		MockingContext<R, arglist...>& operator()(std::function<bool(arglist& ...)> matcher)
		{
			MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher);
			return *this;
		}

		void operator=(std::function<R(arglist& ...)> method)
		{
			MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method);
		}

		template<typename U = R>
		typename std::enable_if<!std::is_reference<U>::value, void>::type operator=(const R& r)
		{
			auto method = [r](const typename fakeit::test_arg<arglist>::type...) -> R
			{ return r; };
			MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method);
		}

		template<typename U = R>
		typename std::enable_if<std::is_reference<U>::value, void>::type operator=(const R& r)
		{
			auto method = [&r](const typename fakeit::test_arg<arglist>::type...) -> R
			{ return r; };
			MethodMockingContext<R, arglist...>::setMethodBodyByAssignment(method);
		}
	};

	template<typename ... arglist>
	class MockingContext<void, arglist...> :
			public MethodMockingContext<void, arglist...>
	{
		MockingContext& operator=(const MockingContext&) = delete;

	public:

		MockingContext(typename MethodMockingContext<void, arglist...>::Context* stubbingContext)
				: MethodMockingContext<void, arglist...>(stubbingContext)
		{
		}

		MockingContext(MockingContext&) = default;

		MockingContext(MockingContext&& other)
				: MethodMockingContext<void, arglist...>(std::move(other))
		{
		}

		MockingContext<void, arglist...>& setMethodDetails(std::string mockName, std::string methodName)
		{
			MethodMockingContext<void, arglist...>::setMethodDetails(mockName, methodName);
			return *this;
		}

		MockingContext<void, arglist...>& Using(const arglist& ... args)
		{
			MethodMockingContext<void, arglist...>::setMatchingCriteria(args...);
			return *this;
		}

		template<class ...arg_matcher>
		MockingContext<void, arglist...>& Using(const arg_matcher& ... arg_matchers)
		{
			MethodMockingContext<void, arglist...>::setMatchingCriteria(arg_matchers...);
			return *this;
		}

		MockingContext<void, arglist...>& Matching(std::function<bool(arglist& ...)> matcher)
		{
			MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher);
			return *this;
		}

		MockingContext<void, arglist...>& operator()(const arglist& ... args)
		{
			MethodMockingContext<void, arglist...>::setMatchingCriteria(args...);
			return *this;
		}

		MockingContext<void, arglist...>& operator()(std::function<bool(arglist& ...)> matcher)
		{
			MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher);
			return *this;
		}

		void operator=(std::function<void(arglist& ...)> method)
		{
			MethodMockingContext<void, arglist...>::setMethodBodyByAssignment(method);
		}

	};

	class DtorMockingContext : public MethodMockingContext<void>
	{
	public:

		DtorMockingContext(MethodMockingContext<void>::Context* stubbingContext)
				: MethodMockingContext<void>(stubbingContext)
		{
		}

		DtorMockingContext(DtorMockingContext& other) : MethodMockingContext<void>(other)
		{
		}

		DtorMockingContext(DtorMockingContext&& other) : MethodMockingContext<void>(std::move(other))
		{
		}

		void operator=(std::function<void()> method)
		{
			MethodMockingContext<void>::setMethodBodyByAssignment(method);
		}

		DtorMockingContext& setMethodDetails(std::string mockName, std::string methodName)
		{
			MethodMockingContext<void>::setMethodDetails(mockName, methodName);
			return *this;
		}
	};

}

namespace fakeit
{


	template<typename C, typename ... baseclasses>
	class MockImpl : private MockObject<C>, public virtual ActualInvocationsSource
	{
	public:

		MockImpl(FakeitContext& fakeit, C& obj)
				: MockImpl<C, baseclasses...>(fakeit, obj, true)
		{
		}

		MockImpl(FakeitContext& fakeit)
				: MockImpl<C, baseclasses...>(fakeit, *(createFakeInstance()), false)
		{
			FakeObject<C, baseclasses...>* fake = asFakeObject(_instanceOwner.get());
			fake->getVirtualTable().setCookie(1, this);
		}

		virtual ~MockImpl() NO_THROWS
		{
			_proxy.detach();
		}


		void getActualInvocations(std::unordered_set<Invocation*>& into) const override
		{
			std::vector<ActualInvocationsSource*> vec;
			_proxy.getMethodMocks(vec);
			for (ActualInvocationsSource* s : vec)
			{
				s->getActualInvocations(into);
			}
		}

		void initDataMembersIfOwner()
		{
			if (isOwner())
			{
				FakeObject<C, baseclasses...>* fake = asFakeObject(_instanceOwner.get());
				fake->initializeDataMembersArea();
			}
		}

		void reset()
		{
			_proxy.Reset();
			initDataMembersIfOwner();
		}

		void clear()
		{
			std::vector<ActualInvocationsContainer*> vec;
			_proxy.getMethodMocks(vec);
			for (ActualInvocationsContainer* s : vec)
			{
				s->clear();
			}
			initDataMembersIfOwner();
		}

		virtual C& get() override
		{
			return _proxy.get();
		}

		virtual FakeitContext& getFakeIt() override
		{
			return _fakeit;
		}

		template<class DATA_TYPE, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type>
		DataMemberStubbingRoot<C, DATA_TYPE> stubDataMember(DATA_TYPE T::*member, const arglist& ... ctorargs)
		{
			_proxy.stubDataMember(member, ctorargs...);
			return DataMemberStubbingRoot<T, DATA_TYPE>();
		}

		template<int id, typename R, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type>
		MockingContext<R, arglist...> stubMethod(R(T::*vMethod)(arglist...))
		{
			return MockingContext<R, arglist...>(new UniqueMethodMockingContextImpl<id, R, arglist...>
					(*this, vMethod));
		}

		DtorMockingContext stubDtor()
		{
			return DtorMockingContext(new DtorMockingContextImpl(*this));
		}


	private:


		std::shared_ptr<FakeObject<C, baseclasses...>> _instanceOwner;
		DynamicProxy<C, baseclasses...> _proxy;
		FakeitContext& _fakeit;

		MockImpl(FakeitContext& fakeit, C& obj, bool isSpy)
				: _instanceOwner(isSpy ? nullptr : asFakeObject(&obj)), _proxy{ obj }, _fakeit(fakeit)
		{
		}

		static FakeObject<C, baseclasses...>* asFakeObject(void* instance)
		{
			return reinterpret_cast<FakeObject<C, baseclasses...>*>(instance);
		}

		template<typename R, typename ... arglist>
		class MethodMockingContextBase : public MethodMockingContext<R, arglist...>::Context
		{
		protected:
			MockImpl<C, baseclasses...>& _mock;

			virtual RecordedMethodBody<R, arglist...>& getRecordedMethodBody() = 0;

		public:
			MethodMockingContextBase(MockImpl<C, baseclasses...>& mock) : _mock(mock)
			{
			}

			virtual ~MethodMockingContextBase() = default;

			void addMethodInvocationHandler(typename ActualInvocation<arglist...>::Matcher* matcher,
					ActualInvocationHandler<R, arglist...>* invocationHandler)
			{
				getRecordedMethodBody().addMethodInvocationHandler(matcher, invocationHandler);
			}

			void scanActualInvocations(const std::function<void(ActualInvocation<arglist...>&)>& scanner)
			{
				getRecordedMethodBody().scanActualInvocations(scanner);
			}

			void setMethodDetails(std::string mockName, std::string methodName)
			{
				getRecordedMethodBody().setMethodDetails(mockName, methodName);
			}

			bool isOfMethod(MethodInfo& method)
			{
				return getRecordedMethodBody().isOfMethod(method);
			}

			ActualInvocationsSource& getInvolvedMock()
			{
				return _mock;
			}

			std::string getMethodName()
			{
				return getRecordedMethodBody().getMethod().name();
			}

		};

		template<typename R, typename ... arglist>
		class MethodMockingContextImpl : public MethodMockingContextBase<R, arglist...>
		{
		protected:

			R (C::*_vMethod)(arglist...);

		public:
			virtual ~MethodMockingContextImpl() = default;

			MethodMockingContextImpl(MockImpl<C, baseclasses...>& mock, R (C::*vMethod)(arglist...))
					: MethodMockingContextBase<R, arglist...>(mock), _vMethod(vMethod)
			{
			}


			virtual std::function<R(arglist& ...)> getOriginalMethod() override
			{
				void* mPtr = MethodMockingContextBase<R, arglist...>::_mock.getOriginalMethod(_vMethod);
				C* instance = &(MethodMockingContextBase<R, arglist...>::_mock.get());
				return [=](arglist& ... args) -> R
				{
					auto m = union_cast<typename VTableMethodType<R, arglist...>::type>(mPtr);
					return m(instance, std::forward<arglist>(args)...);
				};
			}
		};


		template<int id, typename R, typename ... arglist>
		class UniqueMethodMockingContextImpl : public MethodMockingContextImpl<R, arglist...>
		{
		protected:

			virtual RecordedMethodBody<R, arglist...>& getRecordedMethodBody() override
			{
				return MethodMockingContextBase<R, arglist...>::_mock.template stubMethodIfNotStubbed<id>(
						MethodMockingContextBase<R, arglist...>::_mock._proxy,
						MethodMockingContextImpl<R, arglist...>::_vMethod);
			}

		public:

			UniqueMethodMockingContextImpl(MockImpl<C, baseclasses...>& mock, R (C::*vMethod)(arglist...))
					: MethodMockingContextImpl<R, arglist...>(mock, vMethod)
			{
			}
		};

		class DtorMockingContextImpl : public MethodMockingContextBase<void>
		{

		protected:

			virtual RecordedMethodBody<void>& getRecordedMethodBody() override
			{
				return MethodMockingContextBase<void>::_mock.stubDtorIfNotStubbed(
						MethodMockingContextBase<void>::_mock._proxy);
			}

		public:
			virtual ~DtorMockingContextImpl() = default;

			DtorMockingContextImpl(MockImpl<C, baseclasses...>& mock)
					: MethodMockingContextBase<void>(mock)
			{
			}

			virtual std::function<void()> getOriginalMethod() override
			{
				C& instance = MethodMockingContextBase<void>::_mock.get();
				return [=, &instance]() -> void
				{
				};
			}

		};

		static MockImpl<C, baseclasses...>* getMockImpl(void* instance)
		{
			FakeObject<C, baseclasses...>* fake = asFakeObject(instance);
			MockImpl<C, baseclasses...>* mock = reinterpret_cast<MockImpl<C, baseclasses...>*>(fake->getVirtualTable().getCookie(
					1));
			return mock;
		}

		bool isOwner()
		{
			return _instanceOwner != nullptr;
		}

		void unmockedDtor()
		{
		}

		void unmocked()
		{
			ActualInvocation<> invocation(Invocation::nextInvocationOrdinal(), UnknownMethod::instance());
			UnexpectedMethodCallEvent event(UnexpectedType::Unmocked, invocation);
			auto& fakeit = getMockImpl(this)->_fakeit;
			fakeit.handle(event);

			std::string format = fakeit.format(event);
			UnexpectedMethodCallException e(format);
			throw e;
		}

		static C* createFakeInstance()
		{
			FakeObject<C, baseclasses...>* fake = new FakeObject<C, baseclasses...>();
			void* unmockedMethodStubPtr = union_cast<void*>(&MockImpl<C, baseclasses...>::unmocked);
			void* unmockedDtorStubPtr = union_cast<void*>(&MockImpl<C, baseclasses...>::unmockedDtor);
			fake->getVirtualTable().initAll(unmockedMethodStubPtr);
			if (VTUtils::hasVirtualDestructor<C>())
				fake->setDtor(unmockedDtorStubPtr);
			return reinterpret_cast<C*>(fake);
		}

		template<typename R, typename ... arglist>
		void* getOriginalMethod(R (C::*vMethod)(arglist...))
		{
			auto vt = _proxy.getOriginalVT();
			auto offset = VTUtils::getOffset(vMethod);
			void* origMethodPtr = vt.getMethod(offset);
			return origMethodPtr;
		}

		void* getOriginalDtor()
		{
			auto vt = _proxy.getOriginalVT();
			auto offset = VTUtils::getDestructorOffset<C>();
			void* origMethodPtr = vt.getMethod(offset);
			return origMethodPtr;
		}

		template<unsigned int id, typename R, typename ... arglist>
		RecordedMethodBody<R, arglist...>& stubMethodIfNotStubbed(DynamicProxy<C, baseclasses...>& proxy,
				R (C::*vMethod)(arglist...))
		{
			if (!proxy.isMethodStubbed(vMethod))
			{
				proxy.template stubMethod<id>(vMethod, createRecordedMethodBody<R, arglist...>(*this, vMethod));
			}
			Destructible* d = proxy.getMethodMock(vMethod);
			RecordedMethodBody<R, arglist...>* methodMock = dynamic_cast<RecordedMethodBody<R, arglist...>*>(d);
			return *methodMock;
		}

		RecordedMethodBody<void>& stubDtorIfNotStubbed(DynamicProxy<C, baseclasses...>& proxy)
		{
			if (!proxy.isDtorStubbed())
			{
				proxy.stubDtor(createRecordedDtorBody(*this));
			}
			Destructible* d = proxy.getDtorMock();
			RecordedMethodBody<void>* dtorMock = dynamic_cast<RecordedMethodBody<void>*>(d);
			return *dtorMock;
		}

		template<typename R, typename ... arglist>
		static RecordedMethodBody<R, arglist...>* createRecordedMethodBody(MockObject<C>& mock,
				R(C::*vMethod)(arglist...))
		{
			return new RecordedMethodBody<R, arglist...>(mock.getFakeIt(), typeid(vMethod).name());
		}

		static RecordedMethodBody<void>* createRecordedDtorBody(MockObject<C>& mock)
		{
			return new RecordedMethodBody<void>(mock.getFakeIt(), "dtor");
		}
	};
}
namespace fakeit
{

	template<typename R, typename... Args>
	struct Prototype;

	template<typename R, typename... Args>
	struct Prototype<R(Args...)>
	{

		typedef R Type(Args...);

		typedef R ConstType(Args...) const;

		template<class C>
		struct MemberType
		{

			typedef Type(C::*type);
			typedef ConstType(C::*cosntType);

			static type get(type t)
			{
				return t;
			}

			static cosntType getconst(cosntType t)
			{
				return t;
			}

		};

	};

	template<int X, typename R, typename C, typename... arglist>
	struct UniqueMethod
	{
		R (C::*method)(arglist...);

		UniqueMethod(R (C::*vMethod)(arglist...)) : method(vMethod)
		{
		}

		int uniqueId()
		{
			return X;
		}


	};

}


namespace fakeit
{
	namespace internal
	{
	}
	using namespace fakeit::internal;

	template<typename C, typename ... baseclasses>
	class Mock : public ActualInvocationsSource
	{
		MockImpl<C, baseclasses...> impl;
	public:
		virtual ~Mock() = default;

		static_assert(std::is_polymorphic<C>::value, "Can only mock a polymorphic type");

		Mock() : impl(Fakeit)
		{
		}

		explicit Mock(C& obj) : impl(Fakeit, obj)
		{
		}

		virtual C& get()
		{
			return impl.get();
		}


		C& operator()()
		{
			return get();
		}

		void Reset()
		{
			impl.reset();
		}

		void ClearInvocationHistory()
		{
			impl.clear();
		}

		template<class DATA_TYPE, typename ... arglist,
				class = typename std::enable_if<std::is_member_object_pointer<DATA_TYPE C::*>::value>::type>
		DataMemberStubbingRoot<C, DATA_TYPE> Stub(DATA_TYPE C::* member, const arglist& ... ctorargs)
		{
			return impl.stubDataMember(member, ctorargs...);
		}

		template<int id, typename R, typename T, typename ... arglist, class = typename std::enable_if<
				!std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
		MockingContext<R, arglist...> stub(R (T::*vMethod)(arglist...) const)
		{
			auto methodWithoutConstVolatile = reinterpret_cast<R (T::*)(arglist...)>(vMethod);
			return impl.template stubMethod<id>(methodWithoutConstVolatile);
		}

		template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
				!std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
		MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...) volatile)
		{
			auto methodWithoutConstVolatile = reinterpret_cast<R(T::*)(arglist...)>(vMethod);
			return impl.template stubMethod<id>(methodWithoutConstVolatile);
		}

		template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
				!std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
		MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...) const volatile)
		{
			auto methodWithoutConstVolatile = reinterpret_cast<R(T::*)(arglist...)>(vMethod);
			return impl.template stubMethod<id>(methodWithoutConstVolatile);
		}

		template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
				!std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
		MockingContext<R, arglist...> stub(R(T::*vMethod)(arglist...))
		{
			return impl.template stubMethod<id>(vMethod);
		}

		template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
				std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
		MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) const)
		{
			auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod);
			return impl.template stubMethod<id>(methodWithoutConstVolatile);
		}

		template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
				std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
		MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) volatile)
		{
			auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod);
			return impl.template stubMethod<id>(methodWithoutConstVolatile);
		}

		template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
				std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
		MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...) const volatile)
		{
			auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod);
			return impl.template stubMethod<id>(methodWithoutConstVolatile);
		}

		template<int id, typename R, typename T, typename... arglist, class = typename std::enable_if<
				std::is_void<R>::value && std::is_base_of<T, C>::value>::type>
		MockingContext<void, arglist...> stub(R(T::*vMethod)(arglist...))
		{
			auto methodWithoutConstVolatile = reinterpret_cast<void (T::*)(arglist...)>(vMethod);
			return impl.template stubMethod<id>(methodWithoutConstVolatile);
		}

		DtorMockingContext dtor()
		{
			return impl.stubDtor();
		}

		void getActualInvocations(std::unordered_set<Invocation*>& into) const override
		{
			impl.getActualInvocations(into);
		}

	};

}

#include <exception>

namespace fakeit
{

	class RefCount
	{
	private:
		int count;

	public:
		void AddRef()
		{
			count++;
		}

		int Release()
		{
			return --count;
		}
	};

	template<typename T>
	class smart_ptr
	{
	private:
		T* pData;
		RefCount* reference;

	public:
		smart_ptr() : pData(0), reference(0)
		{
			reference = new RefCount();
			reference->AddRef();
		}

		smart_ptr(T* pValue) : pData(pValue), reference(0)
		{
			reference = new RefCount();
			reference->AddRef();
		}

		smart_ptr(const smart_ptr<T>& sp) : pData(sp.pData), reference(sp.reference)
		{
			reference->AddRef();
		}

		~smart_ptr() THROWS
		{
			if (reference->Release() == 0)
			{
				delete reference;
				delete pData;
			}
		}

		T& operator*()
		{
			return *pData;
		}

		T* operator->()
		{
			return pData;
		}

		smart_ptr<T>& operator=(const smart_ptr<T>& sp)
		{
			if (this != &sp)
			{


				if (reference->Release() == 0)
				{
					delete reference;
					delete pData;
				}


				pData = sp.pData;
				reference = sp.reference;
				reference->AddRef();
			}
			return *this;
		}
	};

}

namespace fakeit
{

	class WhenFunctor
	{

		struct StubbingChange
		{

			friend class WhenFunctor;

			virtual ~StubbingChange() THROWS
			{

				if (UncaughtException())
				{
					return;
				}

				_xaction.commit();
			}

			StubbingChange(StubbingChange& other) :
					_xaction(other._xaction)
			{
			}

		private:

			StubbingChange(Xaction& xaction)
					: _xaction(xaction)
			{
			}

			Xaction& _xaction;
		};

	public:

		template<typename R, typename ... arglist>
		struct MethodProgress : MethodStubbingProgress<R, arglist...>
		{

			friend class WhenFunctor;

			virtual ~MethodProgress() override = default;

			MethodProgress(MethodProgress& other) :
					_progress(other._progress), _context(other._context)
			{
			}

			MethodProgress(StubbingContext<R, arglist...>& xaction) :
					_progress(new StubbingChange(xaction)), _context(xaction)
			{
			}

		protected:

			virtual MethodStubbingProgress<R, arglist...>& DoImpl(Action<R, arglist...>* action) override
			{
				_context.appendAction(action);
				return *this;
			}

		private:
			smart_ptr<StubbingChange> _progress;
			StubbingContext<R, arglist...>& _context;
		};


		WhenFunctor()
		{
		}

		template<typename R, typename ... arglist>
		MethodProgress<R, arglist...> operator()(const StubbingContext<R, arglist...>& stubbingContext)
		{
			StubbingContext<R, arglist...>& rootWithoutConst = const_cast<StubbingContext<R, arglist...>&>(stubbingContext);
			MethodProgress<R, arglist...> progress(rootWithoutConst);
			return progress;
		}

	};

}
namespace fakeit
{

	class FakeFunctor
	{
	private:
		template<typename R, typename ... arglist>
		void fake(const StubbingContext<R, arglist...>& root)
		{
			StubbingContext<R, arglist...>& rootWithoutConst = const_cast<StubbingContext<R, arglist...>&>(root);
			rootWithoutConst.appendAction(new ReturnDefaultValue<R, arglist...>());
			rootWithoutConst.commit();
		}

		void operator()()
		{
		}

	public:

		template<typename H, typename ... M>
		void operator()(const H& head, const M& ... tail)
		{
			fake(head);
			this->operator()(tail...);
		}

	};

}

#include <set>
#include <set>


namespace fakeit
{

	struct InvocationUtils
	{

		static void sortByInvocationOrder(std::unordered_set<Invocation*>& ivocations,
				std::vector<Invocation*>& result)
		{
			auto comparator = [](Invocation* a, Invocation* b) -> bool
			{
				return a->getOrdinal() < b->getOrdinal();
			};
			std::set<Invocation*, bool (*)(Invocation* a, Invocation* b)> sortedIvocations(comparator);
			for (auto i : ivocations)
				sortedIvocations.insert(i);

			for (auto i : sortedIvocations)
				result.push_back(i);
		}

		static void collectActualInvocations(std::unordered_set<Invocation*>& actualInvocations,
				std::vector<ActualInvocationsSource*>& invocationSources)
		{
			for (auto source : invocationSources)
			{
				source->getActualInvocations(actualInvocations);
			}
		}

		static void selectNonVerifiedInvocations(std::unordered_set<Invocation*>& actualInvocations,
				std::unordered_set<Invocation*>& into)
		{
			for (auto invocation : actualInvocations)
			{
				if (!invocation->isVerified())
				{
					into.insert(invocation);
				}
			}
		}

		static void collectInvocationSources(std::vector<ActualInvocationsSource*>&)
		{
		}

		template<typename ... list>
		static void collectInvocationSources(std::vector<ActualInvocationsSource*>& into,
				const ActualInvocationsSource& mock,
				const list& ... tail)
		{
			into.push_back(const_cast<ActualInvocationsSource*>(&mock));
			collectInvocationSources(into, tail...);
		}

		static void collectSequences(std::vector<Sequence*>&)
		{
		}

		template<typename ... list>
		static void collectSequences(std::vector<Sequence*>& vec, const Sequence& sequence, const list& ... tail)
		{
			vec.push_back(&const_cast<Sequence&>(sequence));
			collectSequences(vec, tail...);
		}

		static void collectInvolvedMocks(std::vector<Sequence*>& allSequences,
				std::vector<ActualInvocationsSource*>& involvedMocks)
		{
			for (auto sequence : allSequences)
			{
				sequence->getInvolvedMocks(involvedMocks);
			}
		}

		template<class T>
		static T& remove_const(const T& s)
		{
			return const_cast<T&>(s);
		}

	};

}

#include <memory>

#include <vector>
#include <unordered_set>

namespace fakeit
{
	struct MatchAnalysis
	{
		std::vector<Invocation*> actualSequence;
		std::vector<Invocation*> matchedInvocations;
		int count;

		void run(InvocationsSourceProxy& involvedInvocationSources, std::vector<Sequence*>& expectedPattern)
		{
			getActualInvocationSequence(involvedInvocationSources, actualSequence);
			count = countMatches(expectedPattern, actualSequence, matchedInvocations);
		}

	private:
		static void getActualInvocationSequence(InvocationsSourceProxy& involvedMocks,
				std::vector<Invocation*>& actualSequence)
		{
			std::unordered_set<Invocation*> actualInvocations;
			collectActualInvocations(involvedMocks, actualInvocations);
			InvocationUtils::sortByInvocationOrder(actualInvocations, actualSequence);
		}

		static int countMatches(std::vector<Sequence*>& pattern, std::vector<Invocation*>& actualSequence,
				std::vector<Invocation*>& matchedInvocations)
		{
			int end = -1;
			int count = 0;
			int startSearchIndex = 0;
			while (findNextMatch(pattern, actualSequence, startSearchIndex, end, matchedInvocations))
			{
				count++;
				startSearchIndex = end;
			}
			return count;
		}

		static void collectActualInvocations(InvocationsSourceProxy& involvedMocks,
				std::unordered_set<Invocation*>& actualInvocations)
		{
			involvedMocks.getActualInvocations(actualInvocations);
		}

		static bool findNextMatch(std::vector<Sequence*>& pattern, std::vector<Invocation*>& actualSequence,
				int startSearchIndex, int& end,
				std::vector<Invocation*>& matchedInvocations)
		{
			for (auto sequence : pattern)
			{
				int index = findNextMatch(sequence, actualSequence, startSearchIndex);
				if (index == -1)
				{
					return false;
				}
				collectMatchedInvocations(actualSequence, matchedInvocations, index, sequence->size());
				startSearchIndex = index + sequence->size();
			}
			end = startSearchIndex;
			return true;
		}


		static void collectMatchedInvocations(std::vector<Invocation*>& actualSequence,
				std::vector<Invocation*>& matchedInvocations, int start,
				int length)
		{
			int indexAfterMatchedPattern = start + length;
			for (; start < indexAfterMatchedPattern; start++)
			{
				matchedInvocations.push_back(actualSequence[start]);
			}
		}


		static bool isMatch(std::vector<Invocation*>& actualSequence,
				std::vector<Invocation::Matcher*>& expectedSequence, int start)
		{
			bool found = true;
			for (unsigned int j = 0; found && j < expectedSequence.size(); j++)
			{
				Invocation* actual = actualSequence[start + j];
				Invocation::Matcher* expected = expectedSequence[j];
				found = found && expected->matches(*actual);
			}
			return found;
		}

		static int findNextMatch(Sequence*& pattern, std::vector<Invocation*>& actualSequence, int startSearchIndex)
		{
			std::vector<Invocation::Matcher*> expectedSequence;
			pattern->getExpectedSequence(expectedSequence);
			for (int i = startSearchIndex; i < ((int)actualSequence.size() - (int)expectedSequence.size() + 1); i++)
			{
				if (isMatch(actualSequence, expectedSequence, i))
				{
					return i;
				}
			}
			return -1;
		}

	};
}

namespace fakeit
{

	struct SequenceVerificationExpectation
	{

		friend class SequenceVerificationProgress;

		~SequenceVerificationExpectation() THROWS
		{
			if (UncaughtException())
			{
				return;
			}
			VerifyExpectation(_fakeit);
		}

		void setExpectedPattern(std::vector<Sequence*> expectedPattern)
		{
			_expectedPattern = expectedPattern;
		}

		void setExpectedCount(const int count)
		{
			_expectedCount = count;
		}

		void setFileInfo(const char* file, int line, const char* callingMethod)
		{
			_file = file;
			_line = line;
			_testMethod = callingMethod;
		}

	private:

		VerificationEventHandler& _fakeit;
		InvocationsSourceProxy _involvedInvocationSources;
		std::vector<Sequence*> _expectedPattern;
		int _expectedCount;

		const char* _file;
		int _line;
		const char* _testMethod;
		bool _isVerified;

		SequenceVerificationExpectation(
				VerificationEventHandler& fakeit,
				InvocationsSourceProxy mocks,
				std::vector<Sequence*>& expectedPattern) :
				_fakeit(fakeit),
				_involvedInvocationSources(mocks),
				_expectedPattern(expectedPattern),
				_expectedCount(-1),
				_line(0),
				_isVerified(false)
		{
		}


		void VerifyExpectation(VerificationEventHandler& verificationErrorHandler)
		{
			if (_isVerified)
				return;
			_isVerified = true;

			MatchAnalysis ma;
			ma.run(_involvedInvocationSources, _expectedPattern);

			if (isAtLeastVerification() && atLeastLimitNotReached(ma.count))
			{
				return handleAtLeastVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count);
			}

			if (isExactVerification() && exactLimitNotMatched(ma.count))
			{
				return handleExactVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count);
			}

			markAsVerified(ma.matchedInvocations);
		}

		std::vector<Sequence*>& collectSequences(std::vector<Sequence*>& vec)
		{
			return vec;
		}

		template<typename ... list>
		std::vector<Sequence*>& collectSequences(std::vector<Sequence*>& vec, const Sequence& sequence,
				const list& ... tail)
		{
			vec.push_back(&const_cast<Sequence&>(sequence));
			return collectSequences(vec, tail...);
		}


		static void markAsVerified(std::vector<Invocation*>& matchedInvocations)
		{
			for (auto i : matchedInvocations)
			{
				i->markAsVerified();
			}
		}

		bool isAtLeastVerification()
		{

			return _expectedCount < 0;
		}

		bool isExactVerification()
		{
			return !isAtLeastVerification();
		}

		bool atLeastLimitNotReached(int actualCount)
		{
			return actualCount < -_expectedCount;
		}

		bool exactLimitNotMatched(int actualCount)
		{
			return actualCount != _expectedCount;
		}

		void handleExactVerificationEvent(VerificationEventHandler& verificationErrorHandler,
				std::vector<Invocation*> actualSequence, int count)
		{
			SequenceVerificationEvent evt(VerificationType::Exact, _expectedPattern, actualSequence, _expectedCount,
					count);
			evt.setFileInfo(_file, _line, _testMethod);
			return verificationErrorHandler.handle(evt);
		}

		void handleAtLeastVerificationEvent(VerificationEventHandler& verificationErrorHandler,
				std::vector<Invocation*> actualSequence, int count)
		{
			SequenceVerificationEvent evt(VerificationType::AtLeast, _expectedPattern, actualSequence, -_expectedCount,
					count);
			evt.setFileInfo(_file, _line, _testMethod);
			return verificationErrorHandler.handle(evt);
		}

	};

}
namespace fakeit
{
	class ThrowFalseEventHandler : public VerificationEventHandler
	{

		void handle(const SequenceVerificationEvent&) override
		{
			throw false;
		}

		void handle(const NoMoreInvocationsVerificationEvent&) override
		{
			throw false;
		}
	};
}


namespace fakeit
{

	struct FakeitContext;

	class SequenceVerificationProgress
	{

		friend class UsingFunctor;

		friend class VerifyFunctor;

		friend class UsingProgress;

		smart_ptr<SequenceVerificationExpectation> _expectationPtr;

		SequenceVerificationProgress(SequenceVerificationExpectation* ptr) : _expectationPtr(ptr)
		{
		}

		SequenceVerificationProgress(
				FakeitContext& fakeit,
				InvocationsSourceProxy sources,
				std::vector<Sequence*>& allSequences) :
				SequenceVerificationProgress(new SequenceVerificationExpectation(fakeit, sources, allSequences))
		{
		}

		virtual void verifyInvocations(const int times)
		{
			_expectationPtr->setExpectedCount(times);
		}

		class Terminator
		{
			smart_ptr<SequenceVerificationExpectation> _expectationPtr;

			bool toBool()
			{
				try
				{
					ThrowFalseEventHandler eh;
					_expectationPtr->VerifyExpectation(eh);
					return true;
				}
				catch (bool e)
				{
					return e;
				}
			}

		public:
			Terminator(smart_ptr<SequenceVerificationExpectation> expectationPtr) : _expectationPtr(expectationPtr)
			{
			};

			operator bool()
			{
				return toBool();
			}

			bool operator!() const
			{
				return !const_cast<Terminator*>(this)->toBool();
			}
		};

	public:

		~SequenceVerificationProgress() THROWS
		{
		};

		operator bool() const
		{
			return Terminator(_expectationPtr);
		}

		bool operator!() const
		{
			return !Terminator(_expectationPtr);
		}

		Terminator Never()
		{
			Exactly(0);
			return Terminator(_expectationPtr);
		}

		Terminator Once()
		{
			Exactly(1);
			return Terminator(_expectationPtr);
		}

		Terminator Twice()
		{
			Exactly(2);
			return Terminator(_expectationPtr);
		}

		Terminator AtLeastOnce()
		{
			verifyInvocations(-1);
			return Terminator(_expectationPtr);
		}

		Terminator Exactly(const int times)
		{
			if (times < 0)
			{
				throw std::invalid_argument(std::string("bad argument times:").append(fakeit::to_string(times)));
			}
			verifyInvocations(times);
			return Terminator(_expectationPtr);
		}

		Terminator Exactly(const Quantity& q)
		{
			Exactly(q.quantity);
			return Terminator(_expectationPtr);
		}

		Terminator AtLeast(const int times)
		{
			if (times < 0)
			{
				throw std::invalid_argument(std::string("bad argument times:").append(fakeit::to_string(times)));
			}
			verifyInvocations(-times);
			return Terminator(_expectationPtr);
		}

		Terminator AtLeast(const Quantity& q)
		{
			AtLeast(q.quantity);
			return Terminator(_expectationPtr);
		}

		SequenceVerificationProgress setFileInfo(const char* file, int line, const char* callingMethod)
		{
			_expectationPtr->setFileInfo(file, line, callingMethod);
			return *this;
		}
	};
}

namespace fakeit
{

	class UsingProgress
	{
		fakeit::FakeitContext& _fakeit;
		InvocationsSourceProxy _sources;

		void collectSequences(std::vector<fakeit::Sequence*>&)
		{
		}

		template<typename ... list>
		void collectSequences(std::vector<fakeit::Sequence*>& vec, const fakeit::Sequence& sequence,
				const list& ... tail)
		{
			vec.push_back(&const_cast<fakeit::Sequence&>(sequence));
			collectSequences(vec, tail...);
		}

	public:

		UsingProgress(fakeit::FakeitContext& fakeit, InvocationsSourceProxy source) :
				_fakeit(fakeit),
				_sources(source)
		{
		}

		template<typename ... list>
		SequenceVerificationProgress Verify(const fakeit::Sequence& sequence, const list& ... tail)
		{
			std::vector<fakeit::Sequence*> allSequences;
			collectSequences(allSequences, sequence, tail...);
			SequenceVerificationProgress progress(_fakeit, _sources, allSequences);
			return progress;
		}

	};
}

namespace fakeit
{

	class UsingFunctor
	{

		friend class VerifyFunctor;

		FakeitContext& _fakeit;

	public:

		UsingFunctor(FakeitContext& fakeit) : _fakeit(fakeit)
		{
		}

		template<typename ... list>
		UsingProgress operator()(const ActualInvocationsSource& head, const list& ... tail)
		{
			std::vector<ActualInvocationsSource*> allMocks{ &InvocationUtils::remove_const(head),
															&InvocationUtils::remove_const(tail)... };
			InvocationsSourceProxy aggregateInvocationsSource{ new AggregateInvocationsSource(allMocks) };
			UsingProgress progress(_fakeit, aggregateInvocationsSource);
			return progress;
		}

	};
}

#include <set>

namespace fakeit
{

	class VerifyFunctor
	{

		FakeitContext& _fakeit;


	public:

		VerifyFunctor(FakeitContext& fakeit) : _fakeit(fakeit)
		{
		}

		template<typename ... list>
		SequenceVerificationProgress operator()(const Sequence& sequence, const list& ... tail)
		{
			std::vector<Sequence*> allSequences{ &InvocationUtils::remove_const(sequence),
												 &InvocationUtils::remove_const(tail)... };

			std::vector<ActualInvocationsSource*> involvedSources;
			InvocationUtils::collectInvolvedMocks(allSequences, involvedSources);
			InvocationsSourceProxy aggregateInvocationsSource{ new AggregateInvocationsSource(involvedSources) };

			UsingProgress usingProgress(_fakeit, aggregateInvocationsSource);
			return usingProgress.Verify(sequence, tail...);
		}

	};

}

#include <set>
#include <memory>

namespace fakeit
{

	class VerifyNoOtherInvocationsVerificationProgress
	{

		friend class VerifyNoOtherInvocationsFunctor;

		struct VerifyNoOtherInvocationsExpectation
		{

			friend class VerifyNoOtherInvocationsVerificationProgress;

			~VerifyNoOtherInvocationsExpectation() THROWS
			{
				if (UncaughtException())
				{
					return;
				}

				VerifyExpectation(_fakeit);
			}

			void setFileInfo(const char* file, int line, const char* callingMethod)
			{
				_file = file;
				_line = line;
				_callingMethod = callingMethod;
			}

		private:

			VerificationEventHandler& _fakeit;
			std::vector<ActualInvocationsSource*> _mocks;

			const char* _file;
			int _line;
			const char* _callingMethod;
			bool _isVerified;

			VerifyNoOtherInvocationsExpectation(VerificationEventHandler& fakeit,
					std::vector<ActualInvocationsSource*> mocks) :
					_fakeit(fakeit),
					_mocks(mocks),
					_line(0),
					_isVerified(false)
			{
			}

			VerifyNoOtherInvocationsExpectation(VerifyNoOtherInvocationsExpectation& other) = default;

			void VerifyExpectation(VerificationEventHandler& verificationErrorHandler)
			{
				if (_isVerified)
					return;
				_isVerified = true;

				std::unordered_set<Invocation*> actualInvocations;
				InvocationUtils::collectActualInvocations(actualInvocations, _mocks);

				std::unordered_set<Invocation*> nonVerifiedInvocations;
				InvocationUtils::selectNonVerifiedInvocations(actualInvocations, nonVerifiedInvocations);

				if (nonVerifiedInvocations.size() > 0)
				{
					std::vector<Invocation*> sortedNonVerifiedInvocations;
					InvocationUtils::sortByInvocationOrder(nonVerifiedInvocations, sortedNonVerifiedInvocations);

					std::vector<Invocation*> sortedActualInvocations;
					InvocationUtils::sortByInvocationOrder(actualInvocations, sortedActualInvocations);

					NoMoreInvocationsVerificationEvent evt(sortedActualInvocations, sortedNonVerifiedInvocations);
					evt.setFileInfo(_file, _line, _callingMethod);
					return verificationErrorHandler.handle(evt);
				}
			}

		};

		fakeit::smart_ptr<VerifyNoOtherInvocationsExpectation> _ptr;

		VerifyNoOtherInvocationsVerificationProgress(VerifyNoOtherInvocationsExpectation* ptr) :
				_ptr(ptr)
		{
		}

		VerifyNoOtherInvocationsVerificationProgress(FakeitContext& fakeit,
				std::vector<ActualInvocationsSource*>& invocationSources)
				: VerifyNoOtherInvocationsVerificationProgress(
				new VerifyNoOtherInvocationsExpectation(fakeit, invocationSources)
		)
		{
		}

		bool toBool()
		{
			try
			{
				ThrowFalseEventHandler ev;
				_ptr->VerifyExpectation(ev);
				return true;
			}
			catch (bool e)
			{
				return e;
			}
		}

	public:


		~VerifyNoOtherInvocationsVerificationProgress() THROWS
		{
		};

		VerifyNoOtherInvocationsVerificationProgress setFileInfo(const char* file, int line,
				const char* callingMethod)
		{
			_ptr->setFileInfo(file, line, callingMethod);
			return *this;
		}

		operator bool() const
		{
			return const_cast<VerifyNoOtherInvocationsVerificationProgress*>(this)->toBool();
		}

		bool operator!() const
		{
			return !const_cast<VerifyNoOtherInvocationsVerificationProgress*>(this)->toBool();
		}

	};

}


namespace fakeit
{
	class VerifyNoOtherInvocationsFunctor
	{

		FakeitContext& _fakeit;

	public:

		VerifyNoOtherInvocationsFunctor(FakeitContext& fakeit) : _fakeit(fakeit)
		{
		}

		void operator()()
		{
		}

		template<typename ... list>
		VerifyNoOtherInvocationsVerificationProgress operator()(const ActualInvocationsSource& head,
				const list& ... tail)
		{
			std::vector<ActualInvocationsSource*> invocationSources{ &InvocationUtils::remove_const(head),
																	 &InvocationUtils::remove_const(tail)... };
			VerifyNoOtherInvocationsVerificationProgress progress{ _fakeit, invocationSources };
			return progress;
		}
	};

}
namespace fakeit
{

	class SpyFunctor
	{
	private:

		template<typename R, typename ... arglist>
		void spy(const SpyingContext<R, arglist...>& root)
		{
			SpyingContext<R, arglist...>& rootWithoutConst = const_cast<SpyingContext<R, arglist...>&>(root);
			auto methodFromOriginalVT = rootWithoutConst.getOriginalMethod();
			rootWithoutConst.appendAction(new ReturnDelegateValue<R, arglist...>(methodFromOriginalVT));
			rootWithoutConst.commit();
		}

		void operator()()
		{
		}

	public:

		template<typename H, typename ... M>
		void operator()(const H& head, const M& ... tail)
		{
			spy(head);
			this->operator()(tail...);
		}

	};

}

#include <vector>
#include <set>

namespace fakeit
{
	class VerifyUnverifiedFunctor
	{

		FakeitContext& _fakeit;

	public:

		VerifyUnverifiedFunctor(FakeitContext& fakeit) : _fakeit(fakeit)
		{
		}

		template<typename ... list>
		SequenceVerificationProgress operator()(const Sequence& sequence, const list& ... tail)
		{
			std::vector<Sequence*> allSequences{ &InvocationUtils::remove_const(sequence),
												 &InvocationUtils::remove_const(tail)... };

			std::vector<ActualInvocationsSource*> involvedSources;
			InvocationUtils::collectInvolvedMocks(allSequences, involvedSources);

			InvocationsSourceProxy aggregateInvocationsSource{ new AggregateInvocationsSource(involvedSources) };
			InvocationsSourceProxy unverifiedInvocationsSource{
					new UnverifiedInvocationsSource(aggregateInvocationsSource) };

			UsingProgress usingProgress(_fakeit, unverifiedInvocationsSource);
			return usingProgress.Verify(sequence, tail...);
		}

	};

	class UnverifiedFunctor
	{
	public:
		UnverifiedFunctor(FakeitContext& fakeit) : Verify(fakeit)
		{
		}

		VerifyUnverifiedFunctor Verify;

		template<typename ... list>
		UnverifiedInvocationsSource operator()(const ActualInvocationsSource& head, const list& ... tail)
		{
			std::vector<ActualInvocationsSource*> allMocks{ &InvocationUtils::remove_const(head),
															&InvocationUtils::remove_const(tail)... };
			InvocationsSourceProxy aggregateInvocationsSource{ new AggregateInvocationsSource(allMocks) };
			UnverifiedInvocationsSource unverifiedInvocationsSource{ aggregateInvocationsSource };
			return unverifiedInvocationsSource;
		}


	};
}

namespace fakeit
{

	static UsingFunctor Using(Fakeit);
	static VerifyFunctor Verify(Fakeit);
	static VerifyNoOtherInvocationsFunctor VerifyNoOtherInvocations(Fakeit);
	static UnverifiedFunctor Unverified(Fakeit);
	static SpyFunctor Spy;
	static FakeFunctor Fake;
	static WhenFunctor When;

	template<class T>
	class SilenceUnusedVariableWarnings
	{

		void use(void*)
		{
		}

		SilenceUnusedVariableWarnings()
		{
			use(&Fake);
			use(&When);
			use(&Spy);
			use(&Using);
			use(&Verify);
			use(&VerifyNoOtherInvocations);
			use(&_);
		}
	};

}
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif

#define MOCK_TYPE(mock) \
    std::remove_reference<decltype(mock.get())>::type

#define OVERLOADED_METHOD_PTR(mock, method, prototype) \
    fakeit::Prototype<prototype>::MemberType<MOCK_TYPE(mock)>::get(&MOCK_TYPE(mock)::method)

#define CONST_OVERLOADED_METHOD_PTR(mock, method, prototype) \
    fakeit::Prototype<prototype>::MemberType<MOCK_TYPE(mock)>::getconst(&MOCK_TYPE(mock)::method)

#define Dtor(mock) \
    mock.dtor().setMethodDetails(#mock,"destructor")

#define Method(mock, method) \
    mock.template stub<__COUNTER__>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method)

#define OverloadedMethod(mock, method, prototype) \
    mock.template stub<__COUNTER__>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define ConstOverloadedMethod(mock, method, prototype) \
    mock.template stub<__COUNTER__>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define Verify(...) \
        Verify( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__)

#define Using(...) \
        Using( __VA_ARGS__ )

#define VerifyNoOtherInvocations(...) \
    VerifyNoOtherInvocations( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__)

#define Fake(...) \
    Fake( __VA_ARGS__ )

#define When(call) \
    When(call)

